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