Подтвердить что ты не робот

Как вызвать статический конструктор с отражением?

Как я могу получить 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);
4b9b3361

Ответ 1

Используйте myClass.TypeInitializer.Invoke(null, null).

Я только что пробовал это, и он работал нормально.

Я бы настоятельно рекомендовал вам не делать этого, однако - он нарушает тип, ожидающий, что статический конструктор будет выполняться только один раз. Используйте RuntimeHelpers.RunClassConstructor в соответствии с Oliver answer, если вы просто пытаетесь обеспечить инициализируется класс.

Ответ 2

Существует также System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(RuntimeTypeHandle type), который дополнительно гарантирует, что статический конструктор вызывается только один раз, независимо от того, сколько раз вызывается метод:

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

Ссылка

Ответ 3

Даже если это возможно, возможно, это не очень хорошая идея. Однако, если вы обращаетесь к любому члену класса, среда выполнения автоматически вызовет для вас статический конструктор. Например:

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

Поскольку доступ к полю класса не может вызвать какого-либо побочного эффекта (кроме инициализации класса и вызова статического конструктора), это должен быть относительно безопасный способ сделать это в целом (однако он будет работать только для классов с некоторым статическим полем). Это имеет то преимущество, что гарантирует, что конструктор типа будет вызываться не более одного раза, что очень важно.

Ответ 4

Вы также попробовали BindingFlags.Private?

Обратите внимание, что статический конструктор гарантированно получает вызов до вызова любого другого экземпляра или статических методов этого класса, и гарантируется быть потокобезопасным и называется ровно один раз.

Если вы явно назовете это отражением, вы можете причинить много вреда.