C#,如何使用Reflection.Emit mvvmlight样式的getter setter动态创建

问题描述 投票:0回答:1

如何在Reflection.Emit中创建如下所示的属性

    private string _Name;

    public override string Name{ get => _Name; set => Set(ref _Name, value); }

我用Reflection.Emmit尝试过这个>
    private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType)
    {
      // propertyName = "Name";
      // propertyType = typeof(string);
      // private string _Name;
      FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);

      // public string Name {get; set;}
      PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
      // get;
      MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
      ILGenerator getIl = getPropMthdBldr.GetILGenerator();
      // get => _Name
      getIl.Emit(OpCodes.Ldarg_0);
      getIl.Emit(OpCodes.Ldfld, fieldBuilder);
      getIl.Emit(OpCodes.Ret);

      // set;
      MethodBuilder setPropMthdBldr =
          tb.DefineMethod("set_" + propertyName,
            MethodAttributes.Public |
            MethodAttributes.SpecialName |
            MethodAttributes.HideBySig,
            null, new[] { propertyType });

      ILGenerator setIl = setPropMthdBldr.GetILGenerator();


      var MvvmLightSetMethod = typeof(ObservableObject)
                               .GetMethods(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.DeclaredOnly)
                               .Where(m => m.Name == "Set").ToList()[2];

      // set => Set(ref _Name, value);
      setIl.Emit(OpCodes.Mkrefany, fieldBuilder);
      setIl.Emit(OpCodes.Ldarg_0);
      setIl.Emit(OpCodes.Ldarg_1);
      setIl.Emit(OpCodes.Stfld, propertyName);
      setIl.Emit(OpCodes.Call, MvvmLightSetMethod);
      setIl.Emit(OpCodes.Ret);

      // public string Name {get; set;}
      propertyBuilder.SetGetMethod(getPropMthdBldr);
      propertyBuilder.SetSetMethod(setPropMthdBldr);
    }

我的问题

如果我运行此代码并调用设置器,则会在set_Name(string)中收到“无效的类令牌异常”

如何在Reflection.Emit私有字符串_Name中创建如下所示的属性;公共替代字符串Name {get => _Name;设置=>设置(ref _Name,value); }我用...

c# mvvm-light inotifypropertychanged reflection.emit
1个回答
0
投票

您打给Set<T>的IL完全错误。

© www.soinside.com 2019 - 2024. All rights reserved.