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
?
Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor.
Quick A: Yes, and there are no ambiguity with static members.
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.
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.
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.
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With