Как вызвать статический конструктор с отражением?
Как я могу получить 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);
Ответы
Ответ 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?
Обратите внимание, что статический конструктор гарантированно получает вызов до вызова любого другого экземпляра или статических методов этого класса, и гарантируется быть потокобезопасным и называется ровно один раз.
Если вы явно назовете это отражением, вы можете причинить много вреда.