首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在实现接口但使用基类中的成员实现的.NET中创建DynamicType

在实现接口但使用基类中的成员实现的.NET中创建DynamicType
EN

Stack Overflow用户
提问于 2011-01-26 13:03:06
回答 2查看 2.3K关注 0票数 12

我正在尝试生成一个实现接口的动态类,但是其中一个或多个成员已经存在于基中。我用C#编译了下面的代码,并在reflector中检查了它,看看C#编译器做了什么。

代码语言:javascript
复制
class BaseClass
{
    public string Bob
    {
        get { return "Bob"; }
    }
}

interface IStuff
{
    string Bob { get; }
}

class SubClass : BaseClass, IStuff
{
}

Reflector在SubClass中没有显示任何实现。

代码语言:javascript
复制
.class private auto ansi beforefieldinit SubClass
    extends Enterprise.Services.OperationalActions.Business.Filters.BaseClass
    implements Enterprise.Services.OperationalActions.Business.Filters.IStuff
{
}

但是如果我没有显式地发出该成员,TypeBuilder.CreateType()就会抛出一个InvalidOperationException,声明该成员没有实现。所以我的问题是,我如何告诉TypeBuilder接口成员应该从基中获取它的实现?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2011-01-26 15:39:34

看起来,对于TypeBuilder,你必须添加一个私有的直通程序,只是为了让它高兴(如下所示)。您也可以尝试使用几乎相同的IKVM构建器,但它可能没有此限制。

代码语言:javascript
复制
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);
    }
}
票数 9
EN

Stack Overflow用户

发布于 2011-01-26 23:39:52

C#编译器实际上会为BaseType发出不同的代码,这取决于您的SubClass定义是否在同一个程序集中。所以如果你只有这个:

代码语言:javascript
复制
interface IStuff
{
    string Bob { get; }
}

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

然后在另一个C#项目中定义SubClass,那么编译器实际上会在其中发出一个显式的接口实现。这是因为在这种情况下,BaseClass.get_Bob将被定义为非虚拟的,这意味着它不能用于满足接口的约定。

另请参阅Why are C# interface methods not declared abstract or virtual?,它在答案的末尾明确讨论了这种奇怪之处。

票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4801537

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档