Dot-Net

在實現介面但使用基類的成員實現的 .NET 中創建 DynamicType

  • June 2, 2018

我正在嘗試生成一個實現介面的動態類,但是其中一個或多個成員已經存在於基礎中。我在 C# 中編譯了以下程式碼,並在反射器中檢查它以查看 C# 編譯器的作用。

class BaseClass
{
   public string Bob
   {
       get { return "Bob"; }
   }
}

interface IStuff
{
   string Bob { get; }
}

class SubClass : BaseClass, IStuff
{
}

Reflector 在 SubClass 中沒有顯示任何實現。

.class private auto ansi beforefieldinit SubClass
   extends Enterprise.Services.OperationalActions.Business.Filters.BaseClass
   implements Enterprise.Services.OperationalActions.Business.Filters.IStuff
{
}

但是,如果我沒有明確地發出成員,TypeBuilder.CreateType()則會拋出一個InvalidOperationException說明該成員沒有實現的聲明。所以我的問題是,我如何告訴TypeBuilder介面成員應該從基礎中獲取它的實現?

看起來TypeBuilder你將不得不添加一個私人直通,只是為了讓它開心(下)。您也可以嘗試使用IKVM builder - 幾乎相同的 API,但它可能沒有此限制。

using System;
using System.Reflection;
using System.Reflection.Emit;
public class BaseClass
{
   public string Bob
   {
       get { return "Bob"; }
   }
}

public interface IStuff
{
   string Bob { get; }
}
static class Program
{
   static void Main()
   {
       var name = new AssemblyName("foo");
       var asm = AppDomain.CurrentDomain.DefineDynamicAssembly(name, AssemblyBuilderAccess.Run);
       var mod = asm.DefineDynamicModule("foo");
       var parent = typeof(BaseClass);
       var type = mod.DefineType("SubClass", parent.Attributes, parent);
       type.AddInterfaceImplementation(typeof(IStuff));

       var bob_get = type.DefineMethod("bob_get", MethodAttributes.Virtual | MethodAttributes.Private,
           typeof(string), Type.EmptyTypes);
       var il = bob_get.GetILGenerator();
       il.Emit(OpCodes.Ldarg_0);
       il.EmitCall(OpCodes.Callvirt, parent.GetProperty("Bob").GetGetMethod(), null);
       il.Emit(OpCodes.Ret);
       type.DefineMethodOverride(bob_get, typeof(IStuff).GetProperty("Bob").GetGetMethod());
       var final = type.CreateType();
       IStuff obj = (IStuff) Activator.CreateInstance(final);
       Console.WriteLine(obj.Bob);
   }
}

引用自:https://stackoverflow.com/questions/4801537