【问题标题】:Emit explicit interface implementation of a property发出属性的显式接口实现
【发布时间】:2020-08-24 15:08:55
【问题描述】:

目标

所以我想做的是在运行时使用TypeBuilder 类创建一个类型。我希望运行时类型从中实现的接口如下所示。

public interface ITest
{
    int TestProperty { get; }
}

应生成的类型应如下所示:

internal class Test : ITest
{
    int ITest.TestProperty { get => 0; }
}

接口的显式实现并不是真正必要的,但这是我发现最多资源的地方。


现在进入实际代码

var assemblyName = new AssemblyName("AssemblyTest");
var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
var module = assemblyBuilder.DefineDynamicModule(assemblyName.Name + ".dll");

var typeBuilder = module.DefineType("TestType", TypeAttributes.NotPublic | TypeAttributes.BeforeFieldInit | TypeAttributes.AutoClass | TypeAttributes.AnsiClass | TypeAttributes.Class, null, new[] { typeof(ITest) });

var prop = typeBuilder.DefineProperty("ITest.TestProperty", PropertyAttributes.HasDefault, typeof(int), null);

var propGet = typeBuilder.DefineMethod("ITest.get_TestProperty", MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.NewSlot | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Final);

var propertyGetIL = propGet.GetILGenerator();

propertyGetIL.Emit(OpCodes.Ldc_I4_0);
propertyGetIL.Emit(OpCodes.Ret);

prop.SetGetMethod(propGet);

typeBuilder.DefineMethodOverride(propGet, typeof(ITest).GetProperty("TestProperty").GetGetMethod());

var type = typeBuilder.CreateType();

仅作为代码的简短说明。

  1. DynamicAssembly/模块/类的创建
  2. 创建支持字段和属性本身
  3. 为属性创建 Get 方法的内容
  4. 将该属性标记为接口的implementation
  5. 创建新类型

但是CreateType 方法向我抛出了以下内容:

方法实现中的主体签名和声明不匹配。类型:“测试类型”。程序集:'AssemblyTest,版本=0.0.0.0,文化=中性,PublicKeyToken=null'。'

我真的不确定我将如何实现该属性以及这是什么原因。

【问题讨论】:

    标签: c# reflection reflection.emit typebuilder


    【解决方案1】:

    定义 get 方法时缺少返回类型。您需要使用different overloadDefineMethod 指定它:

    var propGet = typeBuilder.DefineMethod("ITest.get_TestProperty", 
      MethodAttributes.Private | MethodAttributes.SpecialName | MethodAttributes.NewSlot | 
      MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Final,
      typeof(int), // <--- return type
      Type.EmptyTypes // <-- parameter types (indexers)
    );
    

    【讨论】:

    • 非常感谢,即使我多次写了那几行,我也真的忘记了返回类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-19
    • 2012-10-26
    • 2010-12-21
    • 1970-01-01
    相关资源
    最近更新 更多