Как вызвать статический конструктор с отражением? - PullRequest
14 голосов
/ 26 марта 2010

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

29 голосов
/ 26 марта 2010

Использование myClass.TypeInitializer.Invoke(null, null).

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

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

28 голосов
/ 26 февраля 2015

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

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

Ссылка

7 голосов
/ 26 марта 2010

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

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

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

2 голосов
/ 26 марта 2010

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...