适用于bool的PropertyBuilder

时间:2018-07-30 13:25:56

标签: c# reflection.emit

我陷入了一个问题,我试图在运行时使用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)

2 个答案:

答案 0 :(得分:2)

正确;有多个错误:

  1. 您需要致电SetGetMethod

    checkBoxPropBldr.SetGetMethod(checkBoxGetPropMthdBldr);
    checkBoxPropBldr.SetSetMethod(checkBoxSetPropMthdBldr);
    
  2. 签名需要不使用索引器

    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方法,因此它是只写属性