C# 4.0 在运行时生成类型
我需要在运行时创建具有属性的类型。 类型必须如下所示:C# 4.0 在运行时生成类型,c#-4.0,il,C# 4.0,Il,我需要在运行时创建具有属性的类型。 类型必须如下所示: public class RunTimeType : BaseType { private string _field1; public string Property1 { get { return _field1; } set { if (_field1 != value) { _field1 = value; OnAft
public class RunTimeType : BaseType
{
private string _field1;
public string Property1
{
get { return _field1; }
set
{
if (_field1 != value)
{
_field1 = value;
OnAfterPropertySet("Property1");
}
}
}
}
问题是如何创建集合方法?现在我使用以下代码:
var propertyName = "Property1";
var onAfterPropertySet = baseType.GetMethod("OnAfterPropertySet",
BindingFlags.Instance | BindingFlags.InvokeMethod |
BindingFlags.NonPublic, null, new[] { typeof(string) },
null);
ILGenerator currSetIL = currSetPropMthdBldr.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, field);
currSetIL.Emit(OpCodes.Ldstr, propertyName);
currSetIL.Emit(OpCodes.Call, onAfterPropertySet);
currSetIL.Emit(OpCodes.Pop);
currSetIL.Emit(OpCodes.Ret);
但是当我试图为属性设置值时,会抛出异常您需要在调用
onAfterPropertySet
以获取此
参数之前执行Ldarg\u 0
。您忘记了相等性测试,并将隐藏的this参数传递给实例方法。最好的方法是先用C语言编写代码:
在发布模式下构建,然后使用ildasm.exe或Reflector查看生成的IL:
IL_0000: ldarg.0
IL_0001: ldfld string ConsoleApplication1.Test::_field1
IL_0006: ldarg.1
IL_0007: call bool [mscorlib]System.String::op_Inequality(string,
string)
IL_000c: brfalse.s IL_0020
IL_000e: ldarg.0
IL_000f: ldarg.1
IL_0010: stfld string ConsoleApplication1.Test::_field1
IL_0015: ldarg.0
IL_0016: ldstr "Property1"
IL_001b: call instance void ConsoleApplication1.Test::OnAfterPropertySet(string)
IL_0020: ret
你想完成什么?生成IL很少是最好的解决方案。我得到targetInvocationException,而内部异常是InvalidProgrameException
IL_0000: ldarg.0
IL_0001: ldfld string ConsoleApplication1.Test::_field1
IL_0006: ldarg.1
IL_0007: call bool [mscorlib]System.String::op_Inequality(string,
string)
IL_000c: brfalse.s IL_0020
IL_000e: ldarg.0
IL_000f: ldarg.1
IL_0010: stfld string ConsoleApplication1.Test::_field1
IL_0015: ldarg.0
IL_0016: ldstr "Property1"
IL_001b: call instance void ConsoleApplication1.Test::OnAfterPropertySet(string)
IL_0020: ret