有没有办法使用.NET Framework 4.0从动态生成的运行时类(例如通过反射)中的内部抽象类继承?
答案 0 :(得分:21)
出于对不可能发生的事情的普遍的堕落感,我试着看看我在尝试创建一个继承自System.CurrentSystemTimeZone
的课程时会走多远(一个mscorlib中的内部类)。它允许你创建一个TypeBuilder
,但当你调用CreateType
时,它会抛出一个TypeLoadException
,并显示消息“访问被拒绝:'System.CurrentSystemTimeZone'。”
稍微有些小问题导致我得出结论,你可以动态创建一个具有强名称的程序集,该程序集将其标识为程序集的友元程序集,其中定义了内部类型。但是,在那种情况下,无论如何你都可以编码class Foo : CurrentSystemTimeZone
,而不会留下任何诡计。
无论如何,代码一直到下面抛出的线条,以防万一有人想在这个想法上尝试一些更不正常的变体,并想要一个起点:
using System;
using System.Reflection;
using System.Reflection.Emit;
using System.Threading;
namespace ReflectPerversely
{
class SuicidallyWrong
{
private static ModuleBuilder mb;
public static Assembly ResolveEvent(Object sender, ResolveEventArgs args)
{
return mb.Assembly;
}
public static void Main(string[] args)
{
Assembly sys = Assembly.GetAssembly(typeof(string));
Type ic = sys.GetType("System.CurrentSystemTimeZone",true);
AssemblyName an = new AssemblyName();
an.Name = "CheatingInternal";
AssemblyBuilder ab = Thread.GetDomain().DefineDynamicAssembly(an, AssemblyBuilderAccess.RunAndSave);
mb = ab.DefineDynamicModule("Mod", "CheatingInternal.dll");
AppDomain currentDom = Thread.GetDomain();
currentDom.TypeResolve += ResolveEvent;
TypeBuilder tb = mb.DefineType("Cheat", TypeAttributes.NotPublic | TypeAttributes.Class, ic);
Type cheatType = tb.CreateType();
}
}
}
答案 1 :(得分:5)
当然可以,你不需要反思。 继承的类只需要在同一个程序集中:)
您还可以在程序集之间设置友谊:http://msdn.microsoft.com/en-us/library/0tke9fxk%28v=VS.100%29.aspx,这将允许访问一个程序集的内部类。 这种方法有时可用于创建需要内部访问已测试程序集的单元测试程序集
答案 2 :(得分:1)
你做不到。您可以使用Assembly.GetType()
不公开的类型,但不能从它们继承。 Jon Skeet explains in this article为什么访问非公开成员通常是一个坏主意,并且比我更深入地回答你的问题。