首先定義Emit動態方法時,DynamicMethod和MethodBuilder的DefineParameter方法不是必須的,因為畢竟構造DynamicMethod或MethodBuilder時你需要指定方法的傳回值類型和參數類型。然後是ILGenerator可以直接用ld_loc(N)或者sd_loc(N)來操作相應的參數就可以了。至於傳回值,直接ret指令就可以。所有如果你沒有特殊需要的話,那麼DefineParameter方法是不需要調用的。
如果想為參數加入名稱,自訂特性,或者其他特殊屬性,DefineParameter就派上用場。
先看一個例子,不用DefineParameter,定義一個動態程式集的方法:
//+ using System.Reflection
//+ using System.Reflection.Emit
var mbuilder = tb.DefineMethod("doo",
MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.Static,
CallingConventions.Standard,
null,
new Type[] { typeof(int) });
var ilgen = mbuilder.GetILGenerator();
var loc = ilgen.DeclareLocal(typeof(int));
ilgen.Emit(OpCodes.Ldarg_0);
ilgen.Emit(OpCodes.Stloc_0);
ilgen.Emit(OpCodes.Ret);
在Reflector中可以看到這樣的IL:
.method public hidebysig static void doo(int32) cil managed
{
.maxstack 1
.locals init (
[0] int32 num)
L_0000: ldarg.0
L_0001: stloc.0
L_0002: ret
}
參數(int32類型)是沒有名稱的。
調用DefineParameter,為參數加入名稱:
mbuilder.DefineParameter(1, ParameterAttributes.None, "參數1");
注意DefineParameter返回ParameterBuilder類型。如果只是為了定義名稱,那麼沒必要使用這個ParameterBuilder。
用ParameterBuilder可以為參數(或者傳回值)加入特性。
代碼:
var pbuilder = mbuilder.DefineParameter(1, ParameterAttributes.None, "參數1");
pbuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(System.Runtime.InteropServices.InAttribute).GetConstructor(new Type[0]), new object[0]));
pbuilder.SetCustomAttribute(new CustomAttributeBuilder(typeof(System.Runtime.InteropServices.OutAttribute).GetConstructor(new Type[0]), new object[0]));
Reflector下再看代碼: