Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I explicitly run the static constructor of an unknown type? [duplicate]

Possible Duplicate:
How do I invoke a static constructor with reflection?

I've got some initialization code in the static constructor of various classes. I can't create instances, nor do I know the types in advance. I would like to ensure the classes are loaded.

I tried this:

fooType.TypeInitializer.Invoke (new object[0]);

But got a MemberAccessException: Type initializer was not callable.

I'm assuming this is because the cctor is private? Is there a way to fix this without changing the architecture?

Edit: I found a workaround using RuntimeHelpers.RunClassConstructor, but this way seems to be barely documented in the MSDN and I'm not sure if it is a hack or a reasonable, prod system like way.

like image 908
mafu Avatar asked Dec 20 '10 12:12

mafu


People also ask

Is it possible to explicitly call a class static constructor?

A static constructor cannot be called directly and is only meant to be called by the common language runtime (CLR). It is invoked automatically.

How do I make a static constructor in C++?

C++ doesn't have static constructors, as Java or C# does, so you usually have to initialize the static data members one by one (independently). This is a limitation because you may want to initialize several static data members in the same loop or algorithm, for example.

How do you call a constructor explicitly in C#?

Working of Constructor in C#It is invoked by the 'new' operator immediately after memory gets allocated to the new object. 2. Explicit constructors (constructors defined by the user) can be parameterless or parameterized.

What is the use of static constructor in C#?

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.


1 Answers

I'm not sure why this works, but as far as I reason (with help from Skeet) if i have a static class

public static class Statics1
{
    public static string Value1 { get; set; }

    static Statics1()
    {
        Console.WriteLine("Statics1 cctor");
        Value1 = "Initialized 1";
    }
}

The code:

Type staticType = typeof (Statics1);
staticType.TypeInitializer.Invoke(null);
or
staticType.TypeInitializer.Invoke(new object[0]);

will throw with an exception, because somehow this resolves to the .ctor, instead of the .cctor of the class.
If I use an explicitly static class, it is treated like an abstract sealed class, so the exception is that an abstract class cannot be instantiated, and if I use a regular class with a static constructor, the exception is that the type initializer is not callable.

But if I use the Invoke overload with two parameters (instance, params), like this:

Type staticType = typeof (Statics1);
staticType.TypeInitializer.Invoke(null, null);

explicitly stating that I am invoking a static method (that's the meaning of the first null - no instance == static), this works and initializes the class.


That said, static constructors are strange beasts. Invoking one in this way will call the static constructor even if it was already executed, i.e., this code:

Console.WriteLine(Statics1.Value1);

Type staticType = typeof (Statics1);
staticType.TypeInitializer.Invoke(null, null);

will call the static constructor twice. So if your cctors have potentially important sideeffects, such as creating files, opening databases, etc, you might want to rethink this approach.

Also, even though I prefer static constructors for reasons of readability, from a performance perspective, field initializers are a bit faster than static constructors

like image 198
SWeko Avatar answered Nov 08 '22 06:11

SWeko