2012-03-27 6 views
3

私はSystem.Reflection.Emit名前空間の使い方を覚えました。私は今ILGeneratorの使用にこのコードを変換しようとしている:どのようにオブジェクトを作成する:コードのこの作品のために新しいオブジェクトの作成をどのように翻訳するのですか?

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

私は3つの質問がありますか?コンストラクタを呼び出す方法とクラスのメソッドを呼び出す方法?助けてください。

+4

C#は舞台裏でやっているものを学ぶための最善の方法は、それはあなたのコードを生成するILを見てではありません。デバッガで逆アセンブリを見る方法を知っていると思いますよね? – dasblinkenlight

+0

ok。皆さん、ありがとうございました。 – 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]タブを使用して

LINQPad IL Output

stloc.0ldloc.0は、コード内の変数である2つの命令:あなたは、生成されたコードを見ることができます。

Iが最初に放出されたILは、コードのこの部分に似ている:

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

すなわち。確かに何の変数、スタック上だけの一時的な保管、および:

LINQPad IL output #2

関連する問題