I have three classes, Base
, Derived
and Final
. Derived
derives from Base
and Final
derives from Derived
. All three classes have a static constructor. Class Derived
as a public static method called Setup
. When I call Final.Setup
, I expect that all three static constructors get executed, but only the one in Derived
gets run.
Here is the sample source code:
abstract class Base
{
static Base()
{
System.Console.WriteLine ("Base");
}
}
abstract class Derived : Base
{
static Derived()
{
System.Console.WriteLine ("Derived");
}
public static void Setup()
{
System.Console.WriteLine ("Setup");
}
}
sealed class Final : Derived
{
static Final()
{
System.Console.WriteLine ("Final");
}
}
This makes only partially sense to me. I understand that calling Final.Setup()
is in fact just an alias for Derived.Setup()
, so skipping the static constructor in Final
seems fair enough. However, why isn't the static constructor of Base
called?
I can fix this by calling into a no-operation static method of Base
or by accessing some dummy static method of Base
. But I was wondering: what is the reasoning behind this apparently strange behavior?
A static constructor is called when (according to TCPL):
- An instance of the class type is created.
- Any of the static members of the class type are referenced.
As an example, consider a class with the static Main
method in which execution begins: if you have a static constructor, it will be called before the Main method is called.
Note that even before a static constructor is executed, any static fields are initialized to their default value and then the static field initializers are executed for those field. Only then, the static constructor (cctor) is executed.
To answer your question more directly: static constructors are not inherited, and they cannot be called directly, hence your Base
cctor will not be called in your scenario, unless you give the abstract Base
class a static method and call that first, i.e. as in Base.Initialize()
, as you already suggested.
About the reasoning, that's simple, thinking C# (in Java this is different): static methods are not inherited, thus static constructors should neither be inherited as this could cause unwanted side effects (a cctor called when nothing references that class).
Static methods belong to the class and there is no inheritance. The fact that you can call Final.Setup
is just a syntactic sugar for calling Derived.Setup, so no static member of Final has been referenced - therefore the static constructor is not called.
Same for Base class - there is no inheritance on static members, so the Base class is not involved in any way here.
The C# rules dictate that static constructors are called before the first instance of the class is created or any static member is touched, ergo, possibly never, as in your case.
来源:https://stackoverflow.com/questions/6503588/why-arent-all-static-constructors-called-in-c-sharp-i-e-those-of-the-parent-c