Saturday, November 04, 2006

Static Constructors


Static Constructors:
  1. Cannot have parameters
static A(int i) {} // error CS0132: 'A.A(int)': a static constructor must be parameterless
  1. Cannot have accessibility modifiers
public static A() {}; // error CS0515: 'A.A()': access modifiers are not allowed on static constructors

  • 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).
  1. 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:

  1. Can have a return statement with no expression terminating it.

Usage:
  1. Can be used to assign computed static fields and static readonly fields

  2. To make sure that the type is not marked with beforefieldinit.


No comments: