如何使用.Net中的反射继承密封类?

时间:2008-09-30 21:03:58

标签: .net inheritance

在你向我开枪之前,我不打算这样做,但是another post的某个人说这是可能的。这怎么可能?我从未听说过使用反射继承任何东西。但我看到了一些奇怪的事情......

5 个答案:

答案 0 :(得分:14)

没有要覆盖的虚函数,在子类化密封类中没有多大意义。

如果您尝试编写带有虚函数的密封类,则会出现以下编译器错误:

// error CS0549: 'Seal.GetName()' is a new virtual member in sealed class 'Seal'

但是,您可以通过在基类中声明虚函数(如此)来将虚函数放入密封类中,

public abstract class Animal
{
    private readonly string m_name;

    public virtual string GetName() { return m_name; }

    public Animal( string name )
    { m_name = name; }
}

public sealed class Seal : Animal
{
    public Seal( string name ) : base(name) {}
}

问题仍然存在,我看不出你如何偷偷通过编译器让你声明一个子类。我尝试使用IronRuby(ruby是所有hackety语言中最黑的)但即使它不会让我。

'密封'部分嵌入到MSIL中,所以我猜测CLR本身实际上强制执行此操作。你必须加载代码,解组,删除'密封'位,然后重新组装,并加载新版本。

答案 1 :(得分:9)

我很抱歉在另一个帖子中发布了错误的假设,我无法正确回忆。使用以下示例,使用Reflection.Emit,显示如何从另一个类派生,但它在运行时失败抛出TypeLoadException。

sealed class Sealed
{
   public int x;
   public int y;
}

class Program
{
   static void Main(string[] args)
   {
      AppDomain ad = Thread.GetDomain();
      AssemblyName an = new AssemblyName();
      an.Name = "MyAssembly";
      AssemblyBuilder ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
      ModuleBuilder mb = ab.DefineDynamicModule("MyModule");
      TypeBuilder tb = mb.DefineType("MyType", TypeAttributes.Class, typeof(Sealed));

      // Following throws TypeLoadException: Could not load type 'MyType' from
      // assembly 'MyAssembly' because the parent type is sealed.
      Type t = tb.CreateType();
   }
}

答案 2 :(得分:1)

MIGHT (如果可以,会增加尺寸)。据freenode上的人说,它将涉及使用Reflection.Emit修改字节代码,并将JIT一组新的字节代码交给它。

不是我知道如何......这正是他们的想法。

答案 3 :(得分:1)

另一张海报可能更多地沿着Reflection.Emit而不是更常见的只读反射API思考。

然而,仍然不可能(至少根据this article)。但是,在您尝试实际执行发出的代码之前,使用Reflection.Emit确实可以将某些东西搞砸了。

答案 4 :(得分:-2)

创建一个名为GenericKeyValueBase的新类

把它放在里面

  public class GenericKeyValueBase<TKey,TValue>
    {
        public TKey Key;
        public TValue Value;

        public GenericKeyValueBase(TKey ItemKey, TValue ItemValue)
        {
            Key = ItemKey;
            Value = ItemValue;
        }
    }

如果您感觉非常酷,那么您可以继续添加/删除(AddAt和RemoveAt)添加到新派生类(并使其成为集合/字典)的扩展方法。

一个简单的实现示例,您可以使用普通的System.Collections.Generic.KeyValuePair作为基础,但可以使用上面的代码

  class GenericCookieItem<TCookieKey, TCookieValue> : GenericKeyValueBase<TCookieKey,TCookieValue>
    {
        public GenericCookieItem(TCookieKey KeyValue, TCookieValue ItemValue) : base(KeyValue, ItemValue)
        {
        }
    }