What Is the Use of Static Constructors

What is the use of static constructors?

No you can't overload it; a static constructor is useful for initializing any static fields associated with a type (or any other per-type operations) - useful in particular for reading required configuration data into readonly fields, etc.

It is run automatically by the runtime the first time it is needed (the exact rules there are complicated (see "beforefieldinit"), and changed subtly between CLR2 and CLR4). Unless you abuse reflection, it is guaranteed to run at most once (even if two threads arrive at the same time).

Why do we need static constructors?

If you compile that class into an assembly, then use ILSpy or similar to disassemble the result, you will notice that all static member initialization is performed in the static constructor.

For instance, the following C# code:

public static class BasicClass
{
static int i = 10;
}

Will produce IL equivalent to:

public static class BasicClass
{
static int i;

static BasicClass()
{
i = 10;
}
}

In other words, direct initialization is only syntactic sugar provided by the C# compiler. Under the hood, a static constructor is still implemented.

Private vs Static constructors in .Net

Static constructors: used for initialising static members.

Private constructors: used when you only want a class to be instantiated from within its own code (typically in a static method). For example:

public class Thing
{
static int Number;

static Thing()
{
Number = 42; // This will only be called once, no matter how many instances of the class are created
}

// This method is the only means for external code to get a new Thing
public static Thing GetNewThing()
{
return new Thing();
}

// This constructor can only be called from within the class.
private Thing()
{
}
}

What's the function of a static constructor in a non static class?

Do you use it to initialize static fields on your instance of the non-static type?

Pretty much, except that static fields (or static members of any kind) aren't associated with instances; they are associated with the type itself, regardless of whether it is a static class or a non-static class.

The documentation lists some properties of static constructors, one of which is:

  • A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.

Here, "before" means "immediately before", and whichever one of those things happens first. This is because a static constructor is only called once per type in a single program execution.



Are there any things to take into consideration when using a static constructor?

Here's the full list as given by the link above, which should give you an idea of what to expect when using a static constructor:

  • A static constructor does not take access modifiers or have parameters.

  • A static constructor is called automatically to initialize the class before the first instance is created or any static members are referenced.

  • A static constructor cannot be called directly.

  • The user has no control on when the static constructor is executed in the program.

  • A typical use of static constructors is when the class is using a log file and the constructor is used to write entries to this file.

  • Static constructors are also useful when creating wrapper classes for unmanaged code, when the constructor can call the LoadLibrary method.

  • If a static constructor throws an exception, the runtime will not invoke it a second time, and the type will remain uninitialized for the lifetime of the application domain in which your program is running.

Besides making sure you don't try to access non-static members, since you're not in an instance constructor, the other main thing you have to consider is that a static constructor is always called at a specific time during program execution. As stated, you cannot control this, other than by controlling when "the first instance is created or any static members are referenced."

How to gain Static Constructor's functionality in JAVA?

You may use static initialization block like this -

class SimpleClass
{
static{

}

}

The static block only gets called once, no matter how many objects of that type is being created.

You may see this link for more details.

Update: static initialization block is called only when the class is loaded into the memory.

Static constructor is called before any static members are referenced

Consider this class:

public static class TestStatic
{
public static int SomeValue = GetValue();

static TestStatic()
{
Console.WriteLine("Constructor");
}

}

And this supporting method:

public static int GetValue()
{
Console.WriteLine("GetValue");
return 5;
}

If you run this code:

Console.WriteLine(TestStatic.SomeValue);

The output you will get is:

GetValue
Constructor
5

So you can see that both of the statements you posted are correct. The constructor is called before the static member (SomeValue) is referenced and the static field initialiser is called before the constructor.

How to invoke a static constructor inside a static class in c#

You can't. As it is written in MSDN Article about Static Classes :

A static class is basically the same as a non-static class, but there
is one difference: a static class cannot be instantiated. In other
words, you cannot use the new keyword to create a variable of the
class type. Because there is no instance variable, you access the
members of a static class by using the class name itself.

Also I will suggest you to read this article too

Static Constructors (C# Programming Guide)

As there is written you can't call static constructor

A static constructor is used to initialize any static data, or to
perform a particular action that needs to be performed once only. It
is called automatically before the first instance is created or any
static members are referenced.

Static constructors have the following properties:

  • A static constructor does not take access modifiers or have parameters.

  • A static constructor is called automatically to initialize the class before the first instance is created or any static members are
    referenced.

  • A static constructor cannot be called directly.

  • The user has no control on when the static constructor is executed in the program

Below is example how the static constructor works.

using System; 
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication6
{
public class Program
{
public static void Main(string[] args)
{
A myClass1WithStaticConstructor = new A();
A myClass2WithStaticConstructor = new A();
}
}
public class A
{
public A()
{
Console.WriteLine("default constructor is called.");
}
static A()
{
Console.WriteLine("static constructor is called.");
}
}
}

And the output will be the following:

static constructor is called.

default constructor is called.

default constructor is called.

So from the output we see that the static constructor was called only for the first time.

Also in case if you want to use it with Static Class here is example for it:

using System; 
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication6
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine(A.abc);
}
}
public static class A
{
public static int abc;

static A()
{
abc=10;
Console.WriteLine("static constructor is called.");
}
}
}

The output will be the following:

static constructor is called.

10

So we see that the static constructor is automatically called in this case too.

Calling of Static Constructor and Instance Constructor

First off, the behaviour is not contradictory at all; it is all consistent with the rules. You just don't know what the rules are.

You should read all of my two-part series on instance constructors and my four-part series on the semantics of static constructors. They start here:

http://blogs.msdn.com/b/ericlippert/archive/2008/02/15/why-do-initializers-run-in-the-opposite-order-as-constructors-part-one.aspx

and here:

http://ericlippert.com/2013/02/06/static-constructors-part-one/

respectively.

Those should clearly answer your question, but in case it is not 100% clear let me sum up. The relevant rules are:

  • Rule One: A static constructor runs before any static field is accessed, before any static method is executed, and before any instance constructor is executed.
  • Rule Two: A derived-class instance constructor calls the base class instance constructor before it runs the derived class instance constructor body.

So what happens when you execute new Child()?

  • Rule One applies. We are about to call the instance constructor of Child, so we must first call the static constructor of Child. So it runs first.
  • After the static constructor of Child returns, the instance constructor of Child runs. Rule Two applies: the first thing the Child instance constructor does before it runs its body is runs the instance constructor of Parent.
  • Rule One applies again. We are about to call the instance contructor of Parent, so we must first call the static constructor of Parent. So it runs.
  • After the static constructor of Parent returns, the instance constructor of Parent runs. Rule Two applies: it invokes the instance constructor of object, which does nothing interesting, and then runs the body of the instance constructor of Parent.
  • Control returns to the instance constructor of Child, and its body runs.

So there you go; the order is the Child static constructor, then the Parent static constructor, then the Parent body, then the Child body.

Now let's look at your second example. What happens when you say new XyzChild?

  • Rule One applies. We are about to call the instance constructor of XyzChild, so we first call the static constructor of XyzChild. It's body starts executing, and...
  • ...Rule One applies again. We are about to access a static field of XyzParent, so XyzParent's static constructor must execute.
  • XyzParent's static constructor executes. It accesses a field, but the static constructor is already in flight on this thread, so it does not recursively trigger the static constructor again. It prints out that it is in the parent.
  • Control returns to the child's static constructor, which prints out that it is in the child.
  • Now the child's instance constructor can run. Rule Two applies: XyzParent's instance constructor runs first.
  • Rule One applies, but the static constructor for XyzParent has already run, so it is skipped.
  • The body of XyzParent's instance constructor executes and returns control to XyzChild's static constructor.
  • The body of XyzChild's instance constructor runs.

So there you go. There's no inconsistency whatsoever; the two rules are applied correctly.



Related Topics



Leave a reply



Submit