布尔值的 PropertyBuilder

PropertyBuilder for bool

我遇到了一个问题,我试图在 运行 时间使用 Reflection.Emit 创建一个布尔值 属性。我正在尝试重现示例 Link Found Here For String Property ,但我无法为布尔值 属性 重现它,我缺少线索有人可以帮助我吗?

这是我试过的代码:

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)

打字错误,都说SetSet:

checkBoxPropBldr.SetSetMethod(checkBoxGetPropMthdBldr);
checkBoxPropBldr.SetSetMethod(checkBoxSetPropMthdBldr);

应该是

checkBoxPropBldr.SetGetMethod(checkBoxGetPropMthdBldr);
checkBoxPropBldr.SetSetMethod(checkBoxSetPropMthdBldr);

使用该代码,您生成的 class 具有 属性,但只有一个 Set 方法,因此它是只写的 属性

对;有多个错误:

  1. 你需要打电话给SetGetMethod:

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

    PropertyBuilder checkBoxPropBldr = myTypeBuilder.DefineProperty("CheckBoxColumn",
            System.Reflection.PropertyAttributes.HasDefault,
            typeof(bool), Type.EmptyTypes);
    

有了那个;它应该工作