2012-03-27 2 views
3

얼마 전에 나는 System.Reflection.Emit 네임 스페이스를 사용하는 법을 배우기 시작했습니다. 지금은 ILGenerator의 사용이 코드를 번역하기 위해 노력하고있어 : 어떻게 객체를 생성하기 : 코드의이 작품에 대한새 개체 만들기를 번역하는 방법?

MyClass c = new MyClass("MyClass"); 
c.Do(":D"); 

나는 세 가지 질문이 있습니까? 컨스트럭터를 호출하는 방법과 클래스의 메서드를 호출하는 방법? 도와주세요.

+4

가장 좋은 방법은 뒤에서 일을 C#을 무엇을 배울 수는 당신의 코드를 생성하는 IL보고하지 않습니다. 디버거에서 디스 어셈블리를 보는 방법을 알고 있다고 가정합니다. – dasblinkenlight

+0

확인. 다들 감사 해요. – user35443

답변

3

다음은 필요한 IL 코드를 보여주는 완전한 예입니다.

당신은 LINQPad이를 테스트 할 수 있습니다

void Main() 
{ 
    // Manual test first 
    MyClass c = new MyClass("MyClass"); 
    c.Do(":D"); 

    var method = new DynamicMethod("dummy", null, Type.EmptyTypes); 
    var il = method.GetILGenerator(); 

    // <stack> = new MyClass("MyClass"); 
    il.Emit(OpCodes.Ldstr, "MyClass"); 
    il.Emit(OpCodes.Newobj, typeof(MyClass).GetConstructor(new[] { typeof(string) })); 

    // <stack>.Do(":D"); 
    il.Emit(OpCodes.Ldstr, ":D"); 
    il.Emit(OpCodes.Call, typeof(MyClass).GetMethod("Do", new[] { typeof(string) })); 

    // return; 
    il.Emit(OpCodes.Ret); 

    var action = (Action)method.CreateDelegate(typeof(Action)); 
    action(); 
} 

public class MyClass 
{ 
    public MyClass(string text) 
    { 
     Console.WriteLine("MyClass(" + text + ")"); 
    } 

    public void Do(string text) 
    { 
     Console.WriteLine("Do(" + text + ")"); 
    } 
} 

출력 :

MyClass(MyClass) 
Do(:D) 
MyClass(MyClass) 
Do(:D) 

덧붙여, 특정 예를 들어, IL 코드를 잡아 LINQPad를 사용할 수 있습니다. (이 같은 클래스의 나뿐만 아니라 클래스를 제거) 저 같이, 위의 예제의 IL-부분을 잘라 보자

void Main() 
{ 
    MyClass c = new MyClass("MyClass"); 
    c.Do(":D"); 
} 

를이 코드를 실행 한 다음 출력의 IL 탭을 사용하여 stloc.0ldloc.0 코드에서 변수

LINQPad IL Output

두 가지 지시 사항 : 당신은 생성 된 코드를 볼 수 있습니다.

일리노이 I는 우선 방출이 코드 부분과 유사하다 :

new MyClass("MyClass").Do(":D"); 

즉. 어떤 변수, 참으로 일시적인 스택에 저장하고 :

LINQPad IL output #2