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