来源:(
http://referencesource.microsoft.com/#mscorlib/system/reflection/emit/ilgenerator.cs,3e110f4a19d1c05e
)
public virtual void Emit(OpCode opcode, MethodInfo meth)
{
//...
if (opcode.Equals(OpCodes.Call) || opcode.Equals(OpCodes.Callvirt) || opcode.Equals(OpCodes.Newobj))
{
EmitCall(opcode, meth, null);
}
else
{
// ...
}
}
正如你所见,
Emit()
电话
EmitCall()
如果
OpCode
是
Call
,
Callvirt
或
Newobj
所以
发射()
与
发射呼叫()
不应该有什么不同。
使用发射
OpCodes.Ldstr
需要类型为的操作数
string
。您要做的是在发出
OpCodes.Call
指示
而不是:
for (byte x = 0; x < numParams; x++)
{
il.Emit(OpCodes.Ldstr, x);
}
试试这个:
switch (numParams)
{
case 0:
break;
case 1:
il.Emit(OpCodes.Ldarg_0);
break;
case 2:
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
break;
case 3:
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldarg_2);
break;
default:
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldarg_1);
il.Emit(OpCodes.Ldarg_2);
il.Emit(OpCodes.Ldarg_3);
for (int i = 4; i < numParams; i++)
{
il.Emit(OpCodes.Ldarg, mb.GetParameters()[i]);
}
break;
}
问题更新后编辑:
必须定义属性
myImplementation
在你的新类型中。
试试这个:
// Create field to back your "myImplementation" property
FieldBuilder newBackingField = tb.DefineField("backingField_myImplementation", typeof(MyInterface), System.Reflection.FieldAttributes.Private);
// Create your "myImplementation" property
PropertyBuilder newProp = tb.DefineProperty("myImplementation", System.Reflection.PropertyAttributes.None, typeof(MyInterface), Type.EmptyTypes);
// Create get-method for your property
MethodBuilder getter = tb.DefineMethod("get_myImplementation", System.Reflection.MethodAttributes.Private);
ILGenerator getterILGen = getter.GetILGenerator();
// Basic implementation (return backing field value)
getterILGen.Emit(OpCodes.Ldarg_0);
getterILGen.Emit(OpCodes.Ldfld, newBackingField);
getterILGen.Emit(OpCodes.Ret);
// Create set-method for your property
MethodBuilder setter = tb.DefineMethod("set_myImplementation", System.Reflection.MethodAttributes.Private);
setter.DefineParameter(1, System.Reflection.ParameterAttributes.None, "value");
ILGenerator setterILGen = setter.GetILGenerator();
// Basic implementation (set backing field)
setterILGen.Emit(OpCodes.Ldarg_0);
setterILGen.Emit(OpCodes.Ldarg_1);
setterILGen.Emit(OpCodes.Stfld, newBackingField);
setterILGen.Emit(OpCodes.Ret);
// Hello1 Method
MethodBuilder hello1 = tb.DefineMethod("Hello1", System.Reflection.MethodAttributes.Public);
ILGenerator il = hello1.GetILGenerator();
// Here, add code to load arguments, if any (as shown previously in answer)
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Call, getter);
il.Emit(OpCodes.Callvirt, typeof(MyInterface).GetMethod("Hello1"));
il.Emit(OpCodes.Ret);