Static initialization of an inherited static member

Consider this code example:

public class A<T> { public static T TheT { get; set; } } public class B : A<string> { static B() { TheT = "Test"; } } public class Program { public static void Main(String[] args) { Console.WriteLine(B.TheT); } } 

Here B.TheT is null. However, changing the Main method as follows:

 public static void Main() { new B(); Console.WriteLine(B.TheT); } 

B.TheT is a "Test" as expected. I can understand that this forces the static constructor to run, but why does this not happen in the first case?

I tried to read the specification and it caught my attention (§10.12):

[...] The execution of the static constructor is started first of the following events to occur in the application domain:

• [...]

• Any of the static members of the class type are specified.

My interpretation of this is that since TheT not a member of B , the static constructor of B does not start. Is it correct?

If this is correct, what would be the best way to let B specify how to initialize TheT ?

+6
source share
3 answers

A.TheT is a "Test", as expected. I can understand that this forces the static constructor to run, but why does this not happen in the first case?

Basically, you didn’t actually refer to B If you look in IL, I think you will find that your code was actually equivalent:

 public static void Main(String[] args) { Console.WriteLine(A<string>.TheT); } 

The compiler designed what you really meant, although you wrote B.TheT .

If this is correct, how would I best give A to indicate how to initialize TheT?

I would try to avoid this, to be honest ... but you can always just add a static method to B :

 public static void Initialize() { // Type initializer will be executed now. } 
+5
source

The static constructor is called before the first access or no later than when the first access is performed. Did you know that it was called upon first access, but not so long ago. However, if access is not performed, it will not be called. Thus, you can not control when only if it is called.

MSDN link

The static constructor is used to initialize any static data or to perform a specific action that needs to be performed only once. It is called automatically before the creation of the first instance or reference to any static members.

0
source

In the second case, it is called a static contructor, and it will call the static constructor of the actual types, and not one of the derived ones. Therefore, in your case, it calls static ctor A<T> =>A<string> and not A

To prove this behavior, follow these steps:

 public class Base { static Base() { "Base static".Dump(); } } public class Derived : Base { static Derived() { "Derived static".Dump(); } public static string temp = "Hello"; } 

and call

 Derived.temp.Dump(); 

You'll get:

 Derived static Hello 

This is what you actually do in your code, you get a derived type A<string> and the default static ctor is called.

0
source

Source: https://habr.com/ru/post/928021/


All Articles