如何使用反射调用静态构造函数?

时间:2010-03-26 16:29:14

标签: c# reflection

如何获取静态构造函数的ConstructorInfo

public class MyClass
{
    public static int SomeValue;

    static MyClass()
    {
        SomeValue = 23;
    }
}

我尝试过以下操作并失败了......

 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);

4 个答案:

答案 0 :(得分:29)

使用myClass.TypeInitializer.Invoke(null, null)

我刚试过这个并且工作正常。

我强烈建议您这样做,但是 - 它违反了一种类型,期望静态构造函数只执行一次。如果你只是想确保一个类被初始化,请按照RuntimeHelpers.RunClassConstructor使用Oliver's answer

答案 1 :(得分:28)

还有System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(RuntimeTypeHandle type),它还可以保证静态构造函数只调用一次,无论调用该方法的次数是多少次:

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

Reference

答案 2 :(得分:7)

尽管有可能,但这样做可能不是一个好主意。但是,如果访问该类的任何成员,运行时将自动为您调用静态构造函数。例如:

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

由于访问类的字段不会导致任何副作用(除了初始化类和调用静态构造函数),这应该是一种相对安全的方法来执行此操作(但是,它将继续工作)仅适用于具有某些静态字段的类)。这样做的好处是可以保证类型构造函数最多只能调用一次,这非常重要。

答案 3 :(得分:2)

您是否也尝试过BindingFlags.Private?

注意,静态构造函数在任何调用此类的任何其他实例或静态方法之前都保证调用get,并且保证它是线程安全的并且只调用一次。

如果你明确地用反射来调用它,你可能会造成很大的伤害。