How do I invoke a static constructor with reflection?
Asked Answered
B

4

20

How can I get the ConstructorInfo for a static constructor?

public class MyClass 
{
    public static int SomeValue;

    static MyClass() 
    {
        SomeValue = 23;
    }
}

I've tried the following and failed....

Type myClass = typeof (MyClass);

// throws exception
myClass.TypeInitializer.Invoke(null);

// returns null (also tried deleting  BindingFlags.Public
ConstructorInfo ci = myClass.GetConstructor(
    BindingFlags.Static | BindingFlags.Public,\
    System.Type.DefaultBinder,
    System.Type.EmptyTypes,
    null);

// returns empty array
ConstructorInfo[] clutchingAtStraws = myClass.GetConstructors
   (BindingFlags.Static | BindingFlags.Public);
Butz answered 26/3, 2010 at 16:29 Comment(0)
O
33

Use myClass.TypeInitializer.Invoke(null, null).

I've just tried this and it worked fine.

I would strongly recommend that you don't do this, however - it violates a type expecting the static constructor to only be executed once. Use RuntimeHelpers.RunClassConstructor as per Oliver's answer if you're just trying to ensure a class is initialized.

Oxalis answered 26/3, 2010 at 16:33 Comment(3)
I needed to access it in order to apply an aspect to it using PostSharp. I guess that still is a valid use case.Devoice
Downvoted, just because next answer is (at least in theory) much safer. p.s. ...Damn it, I just downvoted Jon Skeet's answer. Am not I bold?Apposite
@AndriyK: Have added a link to RunClassConstructor, and given credit to Oliver's answer.Oxalis
L
40

There is also System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(RuntimeTypeHandle type), which additionally guarantees that the static constructor is only called once, regardless how many times the method is called:

Type myClass = typeof(MyClass);
System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(myClass.TypeHandle);

Reference

Lamaism answered 26/2, 2015 at 9:6 Comment(0)
O
33

Use myClass.TypeInitializer.Invoke(null, null).

I've just tried this and it worked fine.

I would strongly recommend that you don't do this, however - it violates a type expecting the static constructor to only be executed once. Use RuntimeHelpers.RunClassConstructor as per Oliver's answer if you're just trying to ensure a class is initialized.

Oxalis answered 26/3, 2010 at 16:33 Comment(3)
I needed to access it in order to apply an aspect to it using PostSharp. I guess that still is a valid use case.Devoice
Downvoted, just because next answer is (at least in theory) much safer. p.s. ...Damn it, I just downvoted Jon Skeet's answer. Am not I bold?Apposite
@AndriyK: Have added a link to RunClassConstructor, and given credit to Oliver's answer.Oxalis
L
7

Even though it is possible, it may not be a good idea to do that. However, if you access any member of the class, the runtime will invoke the static constructor automatically for you. For example:

// Read the field 'SomeValue', so that the runtime invokes static ctor   
Type myClass = typeof(MyClass);
myClass.GetField("SomeValue").GetValue(null);

Since accessing a field of the class cannot cause any side-effect (other than initialization of the class and call to the static constructor), this should be a relatively safe way to do this in general (however, it will stil work only for classes with some static field). This has the benefit that it guarantees that the type constructor will be invoked at most once which is quite important.

Lightness answered 26/3, 2010 at 16:37 Comment(2)
Weird, but I came to this question just because readonly field I needed wasn't initiated at the time when I was accessing it. I can bet, that most people are here for very same reason.Apposite
No it does not. Thats why I came here. @Andriy_K +1Climate
S
2

Did you also try BindingFlags.Private?

Note, that the static constructor is guaranteed the get called before any call the any other instance or static methods of this class, and it is guaranteed the be threadsafe and called exactly once.

If you would explicitly call it with reflection you could do lots of harm..

Sunroom answered 26/3, 2010 at 16:33 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.