views:

111

answers:

3

I have a simple class which has a static constructor and a instance constructor. Now when i initialized the class , both static and instance constructor are called. Only static is referred once in a application domain . Can i again call the same class initialization and static constructor initialize again? I have tried but it didn't happen? Is there any way we can call static constructor again in main() method after using garbage collection on the class.

Here is the code:

public class Employee
{
    public Employee()
    {
        Console.WriteLine("Instance constructor called");   
    }

    static Employee()
    {
        Console.WriteLine("Static constructor called");   
    }

    ~Employee()
     {
        //Dispose();
     }
}

Now in main method call:

static void Main(string[] args)
{
    Employee emp = new Employee();
    Employee emp = new Employee();
}

Output:

Static constructor called Instance constructor called Instance constructor called

Now the static didn't called again. Because it is called once in application domain. But is their any way we could call it again without unloading application domain. Can we use GC class over here?

Thanks. Pal

+6  A: 

Unless you prod it with reflection, the static constructor (or more generally, the type initializer) is only executed once per concrete class, per AppDomain.

Note that for generics, using different type arguments you'll get different concrete classes:

public class Foo<T>
{
    Foo()
    {
        Console.WriteLine("T={0}", typeof(T));
    }
    public static void DummyMethod() {}
}
...
Foo<int>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Executes static constructor first
Foo<string>.DummyMethod(); // Type is already initialized; no more output
Jon Skeet
+1  A: 

Not possible. The CLR keeps an internal status bit that tracks whether the type initializer was started. It cannot run again. That status bit is indeed stored in the loader heap as part of the AppDomain state. The workaround is simple, just add a static method to the class.

Hans Passant
A: 

The point of a constructor is to put things into a desired initial valid state.

An instance constructor puts an instance into an initial valid state.

An instance constructor that takes arguments puts an instance into a initial valid state that reflects its arguments.

A static constructor puts the type into an initial valid state. E.g. initialising static members used by the class' static methods or shared by all instances.

Ideally all methods will leave the object and the type in a valid state, but constructors differ in being responsible for getting it into one in the first place.

Any attempt to call a constructor twice is therefore a mistake, since "put it into an initial valid state again" isn't something you can logically do twice ("initial" and "again" don't work well in the same clause). We are helped by the compiler (in it refusing to compile) and the language (in there being no way to express this) from doing such a thing.

And, being a logical impossibility it isn't something you can actually want to do (well, I can want to draw a triangle with more than 3 sides, but only to say that I did). This suggests that you are using your constructor to do something other than setting up an initial valid state.

Doing anything other than establishing such a valid state in a constructor is (as is failing to do so) at best an optimisation, quite often a serious design flaw and quite possibly (worse of all because it goes unfixed longer) an attempted optimisation that is really a serious design flaw.

One sign that your attempt at an optimisation is really a design flaw is a desire to call a static constructor more than once, or to call an instance constructor more than once on the same object.

Identify the desired repeatable behaviour, move it into a separate method, and have it called as needed from both the constructor and elsewhere. Then double check your design's logic, as this is quite a serious mistake to find in a class design and suggests you've got deeper problems.

Jon Hanna