Static Constructors:
- Cannot have parameters
- Cannot have accessibility modifiers
- Cannot be called explicitly
- Called when the class is loaded for the first time
- Run at most once per application domain
- Can be declared for a struct as well
- Execution is triggered by when an instance of the class is created or any of the static members of the class are referenced.
- For a type is run at most once per application domain.
- That are marked extern usually specifies a DllImport attribute. Note that the keyword here is usually. The compiler doesn’t mandate you to specify one. It merely generates a warning when the following is compiled into a library or application.
- TestSC.cs(3,16): warning CS0626: Method, operator, or accessor 'A.A()' is marked external and has no attributes on it. Consider adding a DllImport attribute to specify the external implementation.
public class A
{
extern static A();
static int i =2;
public static void Main() { return; }
}
Upon execution of the application it throws a TypeLoadException:
Unhandled Exception: System.TypeLoadException: Could not load type 'A' from assembly 'TestSC, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null' because the method '.cctor' has no implementation (no RVA).
- When present in a class force the compiler to omit beforefieldinit declaration. The following text discusses ramifications.
Verbatim from C# Specification v.1.0: If a static constructor exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class
Program #1
//Whether field i or j would be initialized first is implementation dependant.
class A
{
static int i = 2;
}
class B
{
static int j = 5;
}
On ILDASM
.class public auto ansi beforefieldinit A
extends [mscorlib]System.Object
{
} // end of class A
Program #2
class Test
{
public static void Main()
{
System.Console.WriteLine(“j = {0}, i={1}”,B.j,A.i);
}
}
class A
{
static int i = 2;
static A() {};
}
class B
{
static int j = 5;
static B() {};
}
Since B.j is used first, field ‘j’ is guaranteed to get initialized first.
On ILDASM
.class public auto ansi A
extends [mscorlib]System.Object
{
} // end of class A
Note that there’s no beforefieldinit in the declaration:
- Can have a return statement with no expression terminating it.
Usage:
- Can be used to assign computed static fields and static readonly fields
- To make sure that the type is not marked with beforefieldinit.
No comments:
Post a Comment