//Create a new derived type.
Car C1 = new Car();
// Implicit conversion to base type is safe.
Vehicle V = C1;
// Explicit conversion is required to cast back to derived type. The code below will compile but throw an exception at run time if the right-side object is not a Car object.
Car C2 = (Car) V;
using System;
namespace Interfaces
{
interface IBankCustomer
{
void DepositMoney();
void WithdrawMoney();
}
public class Demo : IBankCustomer
{
public void DepositMoney()
{
Console.WriteLine("Deposit Money");
}
public void WithdrawMoney()
{
Console.WriteLine("Withdraw Money");
}
public static void Main()
{
Demo DemoObject = new Demo();
DemoObject.DepositMoney();
DemoObject.WithdrawMoney();
}
}
}
Can an Interface contain fields?
No, an Interface cannot contain fields.
What is the difference between class inheritance and interface inheritance?
Can an interface inherit from another interface?
Yes, an interface can inherit from another interface. It is possible for a class to inherit an interface multiple times, through base classes or interfaces it inherits. In this case, the class can only implement the interface one time, if it is declared as part of the new class. If the inherited interface is not declared as part of the new class, its implementation is provided by the base class that declared it. It is possible for a base class to implement interface members using virtual members; in that case, the class inheriting the interface can change the interface behavior by overriding the virtual members.
Option 2: If the class does not wish to provide Implementation for all the members inheirted from the interface, then the class has to be marked as abstract.
namespace Interfaces
{
interface Interface1
{
void Interface1Method();
}
abstract class BaseClass1 : Interface1
{
abstract public void Interface1Method();
public void BaseClass1Method()
{
Console.WriteLine("BaseClass1 Method");
}
}
}
A class inherits from 2 interfaces and both the interfaces have the same method name as shown below. How should the class implement the drive method for both Car and Bus interface?
class Demo : Car,Bus
{
void Car.Drive()
{
Console.WriteLine("Drive Car");
}
void Bus.Drive()
{
Console.WriteLine("Drive Bus");
}
static void Main()
{
Demo DemoObject = new Demo();
((Car)DemoObject).Drive();
((Bus)DemoObject).Drive();
}
}
}
What do you mean by "Explicitly Implemeting an Interface". Give an example?
If a class is implementing the inherited interface member by prefixing the name of the interface, then the class is "Explicitly Implemeting an Interface member". The disadvantage of Explicitly Implemeting an Interface member is that, the class object has to be type casted to the interface type to invoke the interface member. An example is shown below.
static void Main()
{
Demo DemoObject = new Demo();
//DemoObject.Drive();
// Error: Cannot call explicitly implemented interface method
// using the class object.
// Type cast the demo object to interface type Car
((Car)DemoObject).Drive();
}
What are the advantages of using partial classes?
1. When working on large projects, spreading a class over separate files enables multiple programmers to work on it at the same time.
2. When working with automatically generated source, code can be added to the class without having to recreate the source file. Visual Studio uses this approach when it creates Windows Forms, Web service wrapper code, and so on. You can create code that uses these classes without having to modify the file created by Visual Studio.
Will the following code compile?
using System;
namespace Nested
{
class ContainerClass
{
class InnerClass
{
public string str = "A string variable in nested class";
}
}
class Demo
{
public static void Main()
{
InnerClass nestedClassObj = new InnerClass();
Console.WriteLine(nestedClassObj.str);
}
}
}
No, the above code will generate a compile time error stating - The type or namespace name 'InnerClass' could not be found (are you missing a using directive or an assembly reference?). This is bcos InnerClass is inside ContainerClass and does not have any access modifier. Hence inner class is like a private member inside ContainerClass. For the above code to compile and run, we should make InnerClass public and use the fully qualified name when creating the instance of the nested class as shown below.
class Demo
{
public static void Main()
{
ContainerClass.InnerClass nestedClassObj = new ContainerClass.InnerClass();
Console.WriteLine(nestedClassObj.str);
}
}
}
Can the nested class access, the Containing class. Give an example?
Yes, the nested class, or inner class can access the containing or outer class as shown in the example below. Nested types can access private and protected members of the containing type, including any inherited private or protected members.
using System;
namespace Nested
{
class ContainerClass
{
string OuterClassVariable = "I am an outer class variable";
public class InnerClass
{
ContainerClass ContainerClassObject = new ContainerClass();
string InnerClassVariable = "I am an Inner class variable";
public InnerClass()
{
Console.WriteLine(ContainerClassObject.OuterClassVariable);
Console.WriteLine(this.InnerClassVariable);
}
}
}
class Demo
{
public static void Main()
{
ContainerClass.InnerClass nestedClassObj = new ContainerClass.InnerClass();
}
}
}
What is the ouput of the following program?
using System;
namespace Nested
{
class ContainerClass
{
public ContainerClass()
{
Console.WriteLine("I am a container class");
}
public class InnerClass : ContainerClass
{
public InnerClass()
{
Console.WriteLine("I am an inner class");
}
}
}
class DemoClass : ContainerClass.InnerClass
{
public DemoClass()
{
Console.WriteLine("I am a Demo class");
}
public static void Main()
{
DemoClass DC = new DemoClass();
}
}
}
Output:
I am a container class
I am an inner class
I am a Demo class
The above program has used the concepts of inheritance and nested classes. The ContainerClass is at the top in the inheritance chain. The nested InnerClass derives from outer ContainerClass. Finally the DemoClass derives from nested InnerClass. As all the 3 classes are related by inheritance we have the above output.
Can you explicitly call a destructor?
No, you cannot explicitly call a destructor. Destructors are invoked automatically by the garbage collector.
Is it possible to force garbage collector to run?
Yes, it possible to force garbage collector to run by calling the Collect() method, but this is not considered a good practice because this might create a performance over head. Usually the programmer has no control over when the garbage collector runs. The garbage collector checks for objects that are no longer being used by the application. If it considers an object eligible for destruction, it calls the destructor(if there is one) and reclaims the memory used to store the object.
Usually in .NET, the CLR takes care of memory management. Is there any need for a programmer to explicitly release memory and resources? If yes, why and how?
If the application is using expensive external resource, it is recommend to explicitly release the resource before the garbage collector runs and frees the object. We can do this by implementing the Dispose method from the IDisposable interface that performs the necessary cleanup for the object. This can considerably improve the performance of the application.
Usually in .NET, the CLR takes care of memory management. Is there any need for a programmer to explicitly release memory and resources? If yes, why and how?
If the application is using expensive external resource, it is recommend to explicitly release the resource before the garbage collector runs and frees the object. We can do this by implementing the Dispose method from the IDisposable interface that performs the necessary cleanup for the object. This can considerably improve the performance of the application.+
We cannot create instances of static classes. Can we have constructors for static classes?
Yes, static classes can also have constructors.
Yes, a class can be prevented from being instantiated by using a private constructor as shown in the example below.
using System;
namespace TestConsole
{
class Program
{
public static void Main()
{
//Error cannot create instance of a class with private constructor
SampleClass SC = new SampleClass();
}
}
class SampleClass
{
double PI = 3.141;
private SampleClass()
{
}
}
}
To well know the useful of generics lets examine the following code:
public class Stack
{
object[] items;
int count;
public void Push(object item) {...}
public object Pop() {...}
}
the use of type object makes the Stack class very flexible, it is not without drawbacks. For example, it is possible to push a value of any type, such a Customer instance, onto a stack.
However, when a value is retrieved, the result of the Pop method must explicitly be cast back to the appropriate type,
Stack stack = new Stack();
stack.Push(new Customer());
Customer c = (Customer)stack.Pop();
If a value of a value type, such as an int, is passed to the Push method, it is automatically boxed. When the int is later retrieved, it must be unboxed with an explicit type cast:
Stack stack = new Stack();
stack.Push(3);
int i = (int)stack.Pop();
Such boxing and unboxing operations add performance overhead since they involve dynamic memory allocations and run-time type checks.
a Customer instance can be pushed on a stack and then accidentally cast it to the wrong type after it is retrieved:
Stack stack = new Stack();
stack.Push(new Customer());
string s = (string)stack.Pop();
While the code above is an improper use of the Stack class, the code is technically speaking correct and a compile-time error is not reported. The problem does not become apparent until the code is executed, at which point an InvalidCastException is thrown.
With generics those problems are all solved. HOW...?
With generics those problems are all solved. HOW...?
public class Stack
{
T[] items;
int count;
public void Push(T item) {...}
public T Pop() {return Default(T);}
}
Generic code: Default : Specifies the default value of the type parameter. This will be null for reference types and zero for value types.
Advantage:
1. When an instance of Stack
2. Generics provide strong typing, meaning for example that it is an error to push an int onto a stack of Customer objects. Just as a Stack
From : http://www.c-sharpcorner.com/UploadFile/aaghany/GenericsinCSharp11102005020818AM/GenericsinCSharp.aspx
These are common questions and one need to know when going for interview.
This written test was for senior software engineer purely contains .net and C# questions.
Question 1: What is OOPs?
Answer: Object oriented programming like C#.
Question 2: What is XPath?
Answer: XPath is used to navigate through the elements and attributed in XML document.
Question 3: What is Strong type and Week type?
Answer: week type language support the any type variable declaration like java script supports var (no specific data type). Strong type language do not support var like C#.
Question 4: What is polymorphism?
Answer: Polymorphism means different forms, two types of polymorphism
1. runtime polymorphism
2. static polymorphism
Question 5: Difference between interface and abstract class?
Answer: Interface can have only function prototype and all functions should be implemented in inherited class. while abstract class can have function implementation.
Question 6: What is WCF, WPF, WWF?
Answer: WCF: windows communication foundation
WPF: Windows presentation foundation
WWF: Windows workflow foundation
Question 7: What is Address, Contract and binding?
Answer: Address: An address that indicates where the endpoint can be found.
Contract: A contract that identifies the operations available.
Binding: A binding that specifies how a client can communicate with the endpoint.
Question 8: What is root class of .NET?
Answer: System.Object
Question 9: What is multicast delegate?
Answer: Multicast delegate is a delegate which allow to execute more than one method in single event.
Question 10: Can web services supports method overloading Explain with and example?
Answer: Yes, its same as simple method overloading just add a [web method] before the methods.
Question 11: What is difference between web services and WCF?
Answer: WCF = Web services + .NET Remoting
Question 12: Difference between View State and Session state?
Answer: View State is a client side storage management and store data while page postback. Session state is server side management and keep user specific data for session.
Question 13: What is machine.config?
Answer: machine.config file apply settings to all applications running on the same machine.
Q14. What is static polymorphism?
A. Overloading is static polymorphism while dynamic polymorphism is overriding.
Q15. Qis it possible to run factorial checker program in multithreaded environment, is there any benefit of doing factorial checking in multithreaded environment, how will you implement factorial number checking program in multithreaded environment?
A. We need to add multithreaded capability in factorial program if there is a need to calculate factorial for very large number.
Q16: Are private class-level variables inherited?
Yes, but they are not accessible. Although they are not visible or accessible via the class interface, they are inherited.
Q17: 1) Avoid the use of ArrayList. Because any objects added into the Arraylist are added as System.Object and when retrieving values back from the arraylist, these objects are to be unboxed to return the actual valuetype. So it is recommended to use the custom typed collections instead of ArrayList. .NET provides a strongly typed collection class for String in System.Collection.Specialized, namely StringCollection. For other type of class, rename the _ClassType attribute in the attached file to your required type.
Q18: 56.请说明在.net中常用的几种页面间传递参数的方法,并说出他们的优缺点。
答:session(viewstate) 简单,但易丢失,can accoss page, lost when user sign out
application 全局, caching,
cookie 简单,但可能不支持,可能被伪造
input ttype="hidden" 简单,可能被伪造
url参数简单,显示于地址栏,长度有限
数据库稳定,安全,但性能相对弱
Q19: 60.在c#中using和new这两个关键字有什么意义,请写出你所知道的意义?using 指令和语句 new 创建实例 new 隐藏基类中方法。
答:using 引入名称空间或者使用非托管资源
new 新建实例或者隐藏父类方法
Q20. 79.public static const int A=1;这段代码有错误么?是什么?
答:const不能用static修饰。
Q21: 46.sleep() 和 wait() 有什么区别?
答:sleep()方法是使线程停止一段时间的方法。在sleep 时间间隔期满后,线程不一定立即恢复执行。这是因为在那个时刻,其它线程可能正在运行而且没有被调度为放弃执行,除非(a)“醒来”的线程具有更高的优先级(b)正在运行的线程因为其它原因而阻塞。
Thread.sleep() sends the current thread into the "Not Runnable" state for some amount of time. The thread keeps the monitors it has aquired -- i.e. if the thread is currently in a synchronized block or method no other thread can enter this block or method. If another thread calls t.interrupt() it will wake up the sleeping thread.
Sleep is a static method, refer the code example
wait()是线程交互时,如果线程对一个同步对像x 发出一个wait()调用,该线程会暂停执行,被调对像进入等待状态,直到被唤醒或等待时间到。
object.wait() sends the current thread into the "Not Runnable" state, like sleep(), but with a twist. Wait is called on a object, not a thread; we call this object the "lock object." Before lock.wait() is called, the current thread must synchronize on the lock object; wait() then releases this lock, and adds the thread to the "wait list" associated with the lock. Later, another thread can synchronize on the same lock object and call lock.notify(). This wakes up the original, waiting thread. Basically, wait()/notify() is like sleep()/interrupt(), only the active thread does not need a direct pointer to the sleeping thread, but only to the shared lock object.
Wait(Object) |
Releases the lock on an object and blocks the current thread until it reacquires the lock. |
Monitor.Wait(this);
Monitor.Pulse(this);
ThreadName.join():
Join |
Blocks the calling thread until a thread terminates, while continuing to perform standard COM and SendMessage pumping. |
Mutex: When two or more threads need to access a shared resource at the same time, the system needs a synchronization mechanism to ensure that only one thread at a time uses the resource. Mutex is a synchronization primitive that grants exclusive access to the shared resource to only one thread. If a thread acquires a mutex, the second thread that wants to acquire that mutex is suspended until the first thread releases the mutex.
Q22: 103.error和exception有什么区别?
答:error 表示恢复不是不可能但很困难的情况下的一种严重问题。比如说内存溢出。不可能指望程序能处理这样的情况。
exception 表示一种设计或实现问题。也就是说,它表示如果程序运行正常,从不会发生的情况
Q23: 107.在C#中,string str = null 与 string str = " " 请尽量使用文字或图像说明其中的区别。
答:null是没有空间引用的;
" " 是空间为0的字符串;
What’s an abstract class?
A class that cannot be instantiated. An abstract class is a class that must be inherited and have the methods overridden. An abstract class is essentially a blueprint for a class without any implementation
5.When do you absolutely have to declare a class as abstract?
1. When the class itself is inherited from an abstract class, but not all base abstract methods have been overridden.
2. When at least one of the methods in the class is abstract.
8.Can you inherit multiple interfaces?
Yes. .NET does support multiple interfaces.
10. What’s the difference between an interface and abstract class?
In an interface class, all methods are abstract - there is no implementation. In an abstract class some methods can be concrete. In an interface class, no accessibility modifiers are allowed. An abstract class may have accessibility modifiers.
3. Can you declare an override method to be static if the original method is not static?
No. The signature of the virtual method must remain the same. (Note: Only the keyword virtual is changed to keyword override)
7. Are private class-level variables inherited?
Yes, but they are not accessible, so looking at it you can honestly say that they are not inherited.
8. Describe the accessibility modifier protected internal.?
It’s available to derived classes and classes within the same Assembly (and naturally from the base class it’s declared in).
C# improvement:
If you are only reading from the XML object, avoid using XMLDocumentt, instead use XPathDocument, which is readonly and so improves performance.
26.根据线程安全的相关知识,分析以下代码,当调用test方法时i>10时是否会引起死锁?并简要说明理由。(http://www.kuqin.com/job/20090314/39870.html)
public void test(int i)
{
lock(this)
{
if (i>10)
{
i--;
test(i);
}
}
}
答:不会发生死锁,(但有一点int是按值传递的,所以每次改变的都只是一个副本,因此不会出现死锁。但如果把int换做一个object,那么死锁会发生.
28.给定以下XML文件,完成算法流程图。
< DriverC >
请画出遍历所有文件名(FileName)的流程图(请使用递归算法)。
34.abstract class和interface有什么区别?
答:
声明方法的存在而不去实现它的类被叫做抽像类(abstract class),它用于要创建一个体现某些基本行为的类,并为该类声明方法,但不能在该类中实现该类的情况。不能创建abstract 类的实例。然而可以创建一个变量,其类型是一个抽像类,并让它指向具体子类的一个实例。不能有抽像构造函数或抽像静态方法。Abstract 类的子类为它们父类中的所有抽像方法提供实现,否则它们也是抽像类为。取而代之,在子类中实现该方法。知道其行为的其它类可以在类中实现这些方法。
接口(interface)是抽像类的变体。在接口中,所有方法都是抽像的。多继承性可通过实现这样的接口而获得。接口中的所有方法都是抽像的,没有一个有程序体。接口只可以定义static final成员变量。接口的实现与子类相似,除了该实现类不能从接口定义中继承行为。当类实现特殊接口时,它定义(即将程序体给予)所有这种接口的方法。然后,它可以在实现了该接口的类的任何对像上调用接口的方法。由于有抽像类,它允许使用接口名作为引用变量的类型。通常的动态联编将生效。引用可以转换到接口类型或从接口类型转换,instanceof 运算符可以用来决定某对象的类是否实现了接口。
35. Final is keyword, the variable declared as final then it can’t modify at the runtime.
Finally is block, its get execute whether exception occur or not in the method.
Finalize is method, it execute before the garbage collector, Finalize cannot be called or overridden.
36. 产生一个int数组,长度为100,并向其中随机插入1-100,并且不能重复。
int[] intArr=new int[100];
ArrayList myList=new ArrayList();
Random rnd=new Random();
while(myList.Count<100)
{
int num=rnd.Next(1,101);
if(!myList.Contains(num))
myList.Add(num);
}
for(int i=0;i<100;i++)
intArr[i]=(int)myList[i];
Singleton - Creational Design Pattern:
Description:
There are at least two solutions or scenario for implementing Singleton Class. The first solution says that there should be only one shared object and reference to that object should be available only through static method like GetInstance() while making the constructor private. A number of clients can be awarded the reference to such shared object. The second solution says that the constructor should be public (as it appears in most cases) but once an object has been instantiated, an exception should be thrown for each successive constructor call ; thus limiting the class to only one object.
在.net(C# or vb.net)中如何取消一个窗体的关闭。
答:private void Form1_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
e.Cancel=true;
}
92.在C#中有一个double型的变量,比如10321.5,比如122235401.21644,作为货币的值如何按各个不同国家的习惯来输出。比如美国用$10,321.50和$122,235,401.22而在英国则为£10 321.50和£122 235 401.22
答:System.Globalization.CultureInfo MyCulture = new System.Globalization.CultureInfo("en-US");
//System.Globalization.CultureInfo MyCulture = new System.Globalization.CultureInfo("en-GB");为英国货币类型
decimal y = 9999999999999999999999999999m;
string str = String.Format(MyCulture,"My amount = {0:c}",y);
93.某一密码仅使用K、L、M、N、O共5个字母,密码中的单词从左向右排列,密码单词必须遵循如下规则:
(1)密码单词的最小长度是两个字母,可以相同,也可以不同
(2) K不可能是单词的第一个字母
(3)如果L出现,则出现次数不止一次
(4) M不能使最后一个也不能是倒数第二个字母
(5) K出现,则N就一定出现
(6) O如果是最后一个字母,则L一定出现
问题一:下列哪一个字母可以放在LO中的O后面,形成一个3个字母的密码单词?
A) K B)L C) M D) N
答案:B
问题二:如果能得到的字母是K、L、M,那么能够形成的两个字母长的密码单词的总数是多少?
A)1个 B)3个 C)6个 D)9个
答案:A
问题三:下列哪一个是单词密码?
A) KLLN B) LOML C) MLLO D)NMKO
答案:C
96.C#可否对内存进行直接的操作?
答:在.net下,.net引用了垃圾回收(GC)功能,它替代了程序员不过在C#中,不能直接实现Finalize方法,而是在析构函数中调用基类的Finalize()方法
The most common use of these methods is in producer/consumer relationships, where one thread is putting work items on a queue, and another thread is taking them off. The consumer thread typically takes items off the list until it's empty, then waits on a lock. The producer thread pulses the lock when it adds an item to the list (or, if you're worried about efficiency, it can pulse the lock only when it adds an item to a previously-empty list). Here's a sample:
You can think of them like doors - when they're in the "signalled" (or "set") state they're open, and when they're in the "non-signalled" (or "reset") state, they're closed. A call to WaitOne()
waits for the door to be opened so the thread can "go through it" in some sense. The difference between the two classes is that an AutoResetEvent
will reset itself to the non-signalled state immediately after a call to WaitOne()
- it's as if anyone going through the door closes it behind them.
using System;
using System.Threading;
class Test
{
static void Main()
{
ManualResetEvent[] events = new ManualResetEvent[10];
for (int i=0; i < events.Length; i++)
{
events[i] = new ManualResetEvent(false);
Runner r = new Runner(events[i], i);
new Thread(new ThreadStart(r.Run)).Start();
}
int index = WaitHandle.WaitAny(events);
Console.WriteLine ("***** The winner is {0} *****",
index);
WaitHandle.WaitAll(events);
Console.WriteLine ("All finished!");
}
}
class Runner
{
static readonly object rngLock = new object();
static Random rng = new Random();
ManualResetEvent ev;
int id;
internal Runner (ManualResetEvent ev, int id)
{
this.ev = ev;
this.id = id;
}
internal void Run()
{
for (int i=0; i < 10; i++)
{
int sleepTime;
// Not sure about the thread safety of Random...
lock (rngLock)
{
sleepTime = rng.Next(2000);
}
Thread.Sleep(sleepTime);
Console.WriteLine ("Runner {0} at stage {1}",
id, i);
}
ev.Set();
}
}
99.Dictionary :
keyvaluePair:
When you have lots of data in objects, you can construct a DataTable and use it to display information in your DataGridView. Additionally, you can use DataTable with SqlAdapter and SqlCommandBuilder to easily insert chunks of data into SQL Server 2005.
101.Customized serilization:
static void Main(string[] args)
{
MyObjectSon obj = new MyObjectSon(10, "我是字符串");
Console.WriteLine("初始对象:");
Console.WriteLine(obj);
Byte[] data = Serialize(obj);
Console.WriteLine("经过序列化和反序列化后:");
Console.WriteLine(DeSerialize(data));
Console.Read();
}
//序列化对象
static Byte[] Serialize(MyObjectSon obj)
{
IFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
formatter.Serialize(ms, obj);
return ms.ToArray();
}
}
//反序列化对象
static MyObjectSon DeSerialize(Byte[] data)
{
IFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream(data))
{
return (MyObjectSon)formatter.Deserialize(ms);
}
}
MemoryStream.ToArray Method
Writes the stream contents to a byte array, regardless of the Position property.
Implement ISerilizable interface , and override GetObjectData
(SerializationInfo info, StreamingContext context)
102. How do you directly call a native function exported from a DLL? - Here’s a quick example of the DllImport attribute in action:
1.
2. using System.Runtime.InteropServices; /
3. class C
4. {
5. [DllImport(/"user32.dll/")]
6. public static extern int MessageBoxA(int h, string m, string c, int type);
7. public static int Main()
8. {
9. return MessageBoxA(0, /"Hello World!/", /"Caption/", 0);
10. }
11.}
The method C.MessageBoxA() is declared with the static and external modifiers, and has the DllImport attribute, which tells the compiler that the implementation comes from the user32.dll
The key difference comes when performance matter. For example, if you are implementing the list that has heavy "INSERT" operation, LinkedList outperforms List. Since LinkedList can do it in O(1) time, but List may need to expand the size of underlying array.
List
An ArrayList is an array that can dynamically grow and shrink.
C# Brainteasers
What is displayed, and why?
using System;
class Base
{
public virtual void Foo(int x)
{
Console.WriteLine ("Base.Foo(int)");
}
}
class Derived : Base
{
public override void Foo(int x)
{
Console.WriteLine ("Derived.Foo(int)");
}
public void Foo(object o)
{
Console.WriteLine ("Derived.Foo(object)");
}
}
class Test
{
static void Main()
{
Derived d = new Derived();
int i = 10;
d.Foo(i);
}
}
Answer: Derived.Foo(object)
is printed - when choosing an overload, if there are any compatible methods declared in a derived class, all signatures declared in the base class are ignored - even if they're overridden in the same derived class!
What will be displayed, why, and how confident are you?
using System;
class Foo
{
static Foo()
{
Console.WriteLine ("Foo");
}
}
class Bar
{
static int i = Init();
static int Init()
{
Console.WriteLine("Bar");
return 0;
}
}
class Test
{
static void Main()
{
Foo f = new Foo();
Bar b = new Bar();
}
}
Answer: On my box, Bar
is printed and then Foo
. This is because Foo
has a static constructor, which cannot be run until the exact point at which the class first has to be initialized. Bar
doesn't have a static constructor though, so the CLR is allowed to initialize it earlier. However, there's nothing to guarantee that Bar
will be printed at all. No static fields have been referenced, so in theory the CLR doesn't have to initialize it at all in our example