A few notes on static constructors in C

  • 2020-06-07 05:12:00
  • OfStack

Static constructors are a new feature of C# and seem to be rarely used. But we need it when we want to initialize some static variables. The constructor belongs to the class, not to the instance, which means that the constructor will only be executed once. This is called automatically by.NET before the first instance is created or any static member is referenced.


class SimpleClass
{
// Static constructor
static SimpleClass()
{
//
}
}

A few things to note when using static constructors:

Static constructors have neither access modifiers nor arguments. Because it's called by.NET, modifiers like public and private don't make sense.

NET will automatically call the static constructor to initialize the class when the first instance of the class is created or any static member is referenced, which means we cannot call the static constructor directly and therefore have no control over when the static constructor executes.

3. A class can only have 1 static constructor.

4. Constructors without arguments can coexist with static constructors. Although the parameter lists are the same, one belongs to the class and one to the instance, so there is no conflict.

5. Run only once at most.

Static constructors cannot be inherited.

7. If no static constructor is written and the class contains static members with initializers, the compiler automatically generates the default static constructor.

Static constructors fun!
The static constructor of a class is also called a type constructor. The static constructor is controlled by CLR:

CLR will select 1 of the following times to call the static constructor:
1, before the first instance of the type is created, or before the first access to a non-inherited field or member of the type. The word "before" here means before and after. The time here is accurate!

2, at some point before the first access to a non-inherited static field or member, the exact moment is uncertain!

Because the call time is uncertain, it is best not to write code that depends on the execution order of a particular static constructor, which can have unpredictable consequences!

Let's look at Demo below and take a closer look at some interesting behavior of static constructors:

Demo1:


static void Main(string[] args)
{
Console.WriteLine(B.strText);  
}
public class A
{
public static string strText;
static A()
{
strText = "aaaa";  
}
}
public class B : A
{
static B()
{
strText = "bbbb";   
}
}

Guess what, one might think that the output is bbbb because accessing B.strText requires a call to the static constructor static B() of the B class. The output is actually aaaa, because strText is the static field of class A, which class B simply inherits, so the static constructor of class A static () is called, so the output is aaaa. There's nothing really to say about that, and I'm sure you can see the result.

Here's Demo 2:

Demo2:


static void Main(string[] args)
{
B b = new B();  
A a = new A();
Console.WriteLine(B.strText);  
}
public class A
{
public static string strText;
static A()
{
strText = "aaaa";   
}
}
public class B : A
{
static B()
{
strText = "bbbb";   
}
}

Guess what the output result is, some people may think it will output aaaa, the reason is that new B() will call static B() before, then new A() need to call static A before, so the result is aaaa, but the actual situation is not if, the correct result is bbbb, reasons are as follows:

In implementation of new B(); Previously, the static constructor of the B class would have called, i.e., it would have called:
static B()
{
strText="bbbb";
}

When strText= "bbbb" is executed, the strText field needs to be accessed. The strText field of B is inherited from the A class, so it needs to call:
static A()
{
strText="aaaa";
}

The value of strText after executing this function is aaaa

The code then goes back to static B() and executes the strText="bbbb" line in static B(), so the value of strText is bbbb

When A a=new A(); The static constructor of A will not be called, because it has already been called and the static function will only be called once in the lifetime of the entire application domain!

Please give me more advice!


Related articles: