我陷入了一个问题,我试图在运行时使用Reflection.Emit创建一个布尔属性。我正在尝试重现示例Link Found Here For String Property,但是我无法重现它的Boolean属性,我错过了一个线索可以帮助我吗?
这是我尝试的代码:
class Program
{
static void Main(string[] args)
{
Type generatedType = newTypeConvert();
object generetedObject = Activator.CreateInstance(generatedType);
var x = generetedObject.GetType().GetProperty("CheckBoxColumn").GetValue(generetedObject, null);
Console.WriteLine(x);
}
private static Type newTypeConvert()
{
var myDomain = Thread.GetDomain();
var myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
// To generate a persistable assembly, specify AssemblyBuilderAccess.RunAndSave.
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName,
AssemblyBuilderAccess.RunAndSave);
// Generate a persistable single-module assembly.
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("CustomDynamicClass", TypeAttributes.Public);
FieldBuilder checkBoxColumnBldr = myTypeBuilder.DefineField("checkBoxColumn", typeof(bool), FieldAttributes.Private);
PropertyBuilder checkBoxPropBldr = myTypeBuilder.DefineProperty("CheckBoxColumn", System.Reflection.PropertyAttributes.HasDefault, typeof(bool), new Type[] { typeof(bool) });
// The property set and property get methods require a special set of attributes.
MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig;
// Define the "get" accessor method for CustomerName.
MethodBuilder checkBoxGetPropMthdBldr = myTypeBuilder.DefineMethod("get_CheckBoxColumn", getSetAttr, typeof(Boolean), Type.EmptyTypes);
ILGenerator checkBoxGetIL = checkBoxGetPropMthdBldr.GetILGenerator();
//checkBoxGetIL.Emit(OpCodes.Ldc_I4_0, bool.FalseString);
checkBoxGetIL.Emit(OpCodes.Ldarg_0);
checkBoxGetIL.Emit(OpCodes.Ldfld, checkBoxColumnBldr);
checkBoxGetIL.Emit(OpCodes.Ret);
// Define the "set" accessor method for CustomerName.
MethodBuilder checkBoxSetPropMthdBldr = myTypeBuilder.DefineMethod("set_CheckBoxColumn", getSetAttr, null, new Type[] { typeof(Boolean) });
ILGenerator checkBoxSetIL = checkBoxSetPropMthdBldr.GetILGenerator();
//checkBoxSetIL.Emit(OpCodes.Ldc_I4_0, bool.FalseString);
checkBoxSetIL.Emit(OpCodes.Ldarg_0);
checkBoxSetIL.Emit(OpCodes.Ldarg_1);
checkBoxSetIL.Emit(OpCodes.Stfld, checkBoxColumnBldr);
checkBoxSetIL.Emit(OpCodes.Ret);
// Last, we must map the two methods created above to our PropertyBuilder to their corresponding behaviors, "get" and "set" respectively.
checkBoxPropBldr.SetSetMethod(checkBoxGetPropMthdBldr);
checkBoxPropBldr.SetSetMethod(checkBoxSetPropMthdBldr);
Type generatedType = myTypeBuilder.CreateType();
// Save the assembly so it can be examined with Ildasm.exe, or referenced by a test program.
myAsmBuilder.Save(myAsmName.Name + ".dll");
generatedType = myTypeBuilder.CreateType();
return generatedType;
}
}
此操作失败,但出现以下异常:
Unhandled Exception: System.ArgumentException: Property Get method was not found.
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, BindingFlags invokeAttr, Binder binder, Object[] index, CultureInfo culture)
at System.Reflection.RuntimePropertyInfo.GetValue(Object obj, Object[] index)
at Program.Main(String[] args)
答案 0 :(得分:2)
正确;有多个错误:
您需要致电SetGetMethod
:
checkBoxPropBldr.SetGetMethod(checkBoxGetPropMthdBldr);
checkBoxPropBldr.SetSetMethod(checkBoxSetPropMthdBldr);
签名需要不使用索引器
PropertyBuilder checkBoxPropBldr = myTypeBuilder.DefineProperty("CheckBoxColumn",
System.Reflection.PropertyAttributes.HasDefault,
typeof(bool), Type.EmptyTypes);
有了那个;它应该工作
答案 1 :(得分:1)
错别字,都说SetSet
:
checkBoxPropBldr.SetSetMethod(checkBoxGetPropMthdBldr);
checkBoxPropBldr.SetSetMethod(checkBoxSetPropMthdBldr);
应该是
checkBoxPropBldr.SetGetMethod(checkBoxGetPropMthdBldr);
checkBoxPropBldr.SetSetMethod(checkBoxSetPropMthdBldr);
使用该代码,您生成的类具有属性,但是只有Set方法,因此它是只写属性