通过反射动态继承内部类

发布于 2024-12-21 05:12:57 字数 62 浏览 1 评论 0原文

有没有办法使用 .NET Framework 4.0 从动态生成的运行时类(例如通过反射)中的内部抽象类继承?

Is there a way to inherit from an internal abstract class in a dynamically generated runtime class (such as via reflection) using .NET Framework 4.0?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

谁许谁一生繁华 2024-12-28 05:12:57

面对不应该发生的事情,出于普遍的反常意识,我尝试了一下,看看我能在尝试创建一个继承自 System.CurrentSystemTimeZone 的类时走多远。 (mscorlib 中的内部类)。它可以让您创建一个 TypeBuilder,但是当您调用 CreateType 时,它会抛出一个 TypeLoadException 并显示消息“访问被拒绝:'System .当前系统时区'。”

稍微摆弄一下,我得出的结论是,您可以动态创建一个程序集,该程序集具有将其标识为定义内部类型的程序集的友元程序集的强名称。但是,在这种情况下,您无论如何都可以编写 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();
        }
    }
}

Out of a general sense of perversity in the face of things that shouldn't be possible, I gave it a go at seeing how far I would get at trying to create a class that inherited from System.CurrentSystemTimeZone (an internal class in mscorlib). It let's you get as far as creating a TypeBuilder but when you call CreateType it throws a TypeLoadException with the message "Access is denied: 'System.CurrentSystemTimeZone'."

A bit more fiddling as led me to conclude that you could create an assembly dynamically which had the strong name that identified it as a friend assembly of the assembly in which the internal type is defined. But then, in that case you could just code class Foo : CurrentSystemTimeZone anyway, with no trickery being left.

Anyway, the code as far as the line which throws is below, just in case anyone is in the mood for trying some even more perverse variant on the idea, and wants a starting point:

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();
        }
    }
}
野侃 2024-12-28 05:12:57

当然可以,而且您不需要为此进行反思。
继承的类只需位于同一个程序集中:)

您还可以在程序集之间设置友谊:http://msdn.microsoft.com/en-us/library/0tke9fxk%28v=VS.100%29.aspx,这将允许访问一个程序集的内部类。
这种方法有时在创建需要内部访问已测试程序集的单元测试程序集时很有用

Sure you can and you don't need reflection for that.
The inherited class just needs to be in the same assembly :)

You can also setup friendship between assemblies: http://msdn.microsoft.com/en-us/library/0tke9fxk%28v=VS.100%29.aspx, which would allow access to internal classes of one assembly.
This approach is sometimes useful in creating Unit-Test assemblies that need internal access to tested assemblies

左耳近心 2024-12-28 05:12:57

你不能。您可以通过 Assembly.GetType() 使用非公共类型,但不能从它们继承。 Jon Skeet 在本文中解释了为什么通常来说访问非公开成员,并比我更深入地回答您的问题。

You can't. You can use types that aren't public using Assembly.GetType(), but you can't inherit from them. Jon Skeet explains in this article why it is generally a bad idea to access non-public members, and answers your question more in-depth than I could.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文