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.
A static constructor cannot be called directly and is only meant to be called by the common language runtime (CLR). It is invoked automatically.
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.
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With