2010-03-26 5 views
12

고정 생성자에 대해 ConstructorInfo을 얻으려면 어떻게해야합니까?리플렉션을 사용하여 정적 생성자를 호출하려면 어떻게해야합니까?

public class MyClass 
{ 
    public static int SomeValue; 

    static MyClass() 
    { 
     SomeValue = 23; 
    } 
} 

내가 해봤 사용 myClass.TypeInitializer.Invoke(null, null) ....

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

답변

27

을 다음과 실패했습니다.

방금 ​​시도했지만 제대로 작동했습니다.

을 사용하지 않는 것이 좋습니다. 정적 생성자가 한 번만 실행될 것으로 예상되는 유형에 위배됩니다. 클래스가 초기화되었는지 확인하려는 경우 Oliver's answer으로 RuntimeHelpers.RunClassConstructor을 사용하십시오.

+0

한 덕분에 존! 대답은 너무 분명한 것 같습니다. * 웃음 * –

+0

[PostSharp를 사용하여 측면을 적용하려면] (http://www.sharpcrafters.com/)에 액세스해야했습니다. 나는 여전히 유효한 유스 케이스라고 생각한다. –

+2

다음 답변이 (적어도 이론 상으로는) 훨씬 안전하기 때문에 Downvoted. p.s. 젠장, 존 스코트의 대답을 그냥 떨어 뜨 렸어. 내가 대담하지 않은가? –

2

BindingFlags.Private도 시도해 봤습니까?

정적 생성자는이 인스턴스의 다른 인스턴스 나 정적 메서드를 호출하기 전에 get 호출을 보장하며 스레드 안전성을 보장 받고 정확히 한 번만 호출된다는 점에 유의하십시오.

당신이 명시 적으로 피해를 많이 할 수있는 반사로 전화를 할 경우

.. 그것이 가능하다하더라도

7

, 그렇게하는 것은 좋은 생각되지 않을 수 있습니다. 그러나 클래스의 멤버에 액세스하면 런타임에서 정적 생성자를 자동으로 호출합니다. 예를 들어, 클래스 필드를 액세스하고 (클래스의 초기화 이외의 정적 생성자 호출) 어떠한 부작용을 유발할 수 있기 때문에

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

이 일반적으로 이렇게 비교적 안전하게되어야 (그러나 정적 필드가있는 클래스의 경우에만 작업을 수행합니다). 이것은 형식 생성자가 최대로 번만 호출되도록 보장하는 이점이 있습니다. 이는 매우 중요합니다.은 매우 중요합니다.

+1

이상하게 들리지만, 필자가 필요로하는 읽기 전용 필드는 내가 액세스하고있을 때 시작되지 않았기 때문에이 질문에 답했다. 대부분의 사람들은 아주 똑같은 이유로 여기 있습니다. –

23

메서드를 호출에 관계없이 얼마나 많은 시간을 추가로 정적 생성자는 한 번만 호출되는 것을 보장하는, 또한 System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(RuntimeTypeHandle type) 있습니다 :

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

Reference

+5

이것은 실제 정답입니다. 그것은 내 인생을 어떤 죽음에서 구해 냈다 !!!! – Xtro

관련 문제