Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Static initialization of inherited static member

Consider this example code:

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 like this:

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

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

I tried reading the spec, and this caught my attention (§10.12):

[...] The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

• [...]

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

My interpretation of this is that since TheT is not a member of B, the static constructor of B is not forced to be run. Is this correct?

If that is correct, how would I best let B specify how to initialize TheT?

like image 654
carlpett Avatar asked Oct 18 '12 11:10

carlpett


People also ask

Can static data members be inherited?

Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor.

Can we inherit static members in C++?

Quick A: Yes, and there are no ambiguity with static members.

How do you initialize a static member?

For the static variables, we have to initialize them after defining the class. To initialize we have to use the class name then scope resolution operator (::), then the variable name. Now we can assign some value. The following code will illustrate the of static member initializing technique.

Where should you initialize a static data member?

The initializer for a static data member is in the scope of the class declaring the member. A static data member can be of any type except for void or void qualified with const or volatile . You cannot declare a static data member as mutable . You can only have one definition of a static member in a program.


1 Answers

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

Basically, you haven't really referenced B. If you look in the IL, I think you'll find that your code was actually equivalent to:

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

The compiler worked out that that's really the member you meant, even though you wrote B.TheT.

If that is correct, how would I best let A specify how to initialize TheT?

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

public static void Initialize() {
    // Type initializer will be executed now.
}
like image 162
Jon Skeet Avatar answered Oct 04 '22 02:10

Jon Skeet