3
不久前我開始學習使用System.Reflection.Emit命名空間。現在我正在努力把這種代碼中使用的ILGenerator的:如何翻譯新的對象創建?
MyClass c = new MyClass("MyClass");
c.Do(":D");
對於這段代碼我有三個問題:如何創建對象?如何調用構造器以及如何調用類的方法?請幫忙。
不久前我開始學習使用System.Reflection.Emit命名空間。現在我正在努力把這種代碼中使用的ILGenerator的:如何翻譯新的對象創建?
MyClass c = new MyClass("MyClass");
c.Do(":D");
對於這段代碼我有三個問題:如何創建對象?如何調用構造器以及如何調用類的方法?請幫忙。
下面是一個完整的示例,顯示必要的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)
順便說一句,你可以使用LINQPad獲得IL代碼擱置了具體的例子。讓我切出的上述示例中的IL-部分,像這樣(I除去類爲好,這是相同的類):
void Main()
{
MyClass c = new MyClass("MyClass");
c.Do(":D");
}
通過執行該代碼,然後使用輸出的IL標籤,你可以看到生成的代碼:
的兩條指令stloc.0
和ldloc.0
是在代碼中的變量。
的IL我發射的第一類似於這段代碼:
new MyClass("MyClass").Do(":D");
即沒有變量,在棧上只是臨時存儲,而事實上:
最好的方式來學習什麼是C#做幕後是看在IL,它生成的代碼。我假設你知道如何看待調試器中的反彙編,對吧? – dasblinkenlight 2012-03-27 16:14:03
好的。謝謝你們。 – user35443 2012-03-27 18:12:21