你如何在 C# 中“覆盖”一个内部类?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/196521/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:37:00  来源:igfitidea点击:

How do you "override" an Internal Class in C#?

c#overridinginternal-class

提问by danmine

There's something I want to customize in the System.Web.Script.Services.ScriptHandlerFactory and other .NET stuff inside an internal class. Unfortunately, it's an internal class. What options do I have when trying to customize a method in this class?

我想在 System.Web.Script.Services.ScriptHandlerFactory 和内部类中的其他 .NET 内容中自定义一些内容。不幸的是,它是一个内部类。在尝试自定义此类中的方法时,我有哪些选择?

回答by Joel Coehoorn

You might find this recent articleenlightening. Basically, it says that you can't override anything marked internal, and the source is about as authoritative as it gets. Best you can hope for is an extension method.

您可能会发现这篇最近的文章很有启发性。基本上,它说你不能覆盖任何标记的东西internal,而且来源几乎是权威的。您最希望的是一种扩展方法。

回答by Kris

The internal keyword signifies that a unit of code (class, method, etc.) is "public" to the assembly it is in, but private to any other assembly.

internal 关键字表示代码单元(类、方法等)对于它所在的程序集是“公共的”,但对于任何其他程序集是私有的。

Because you are not in the same assembly, you cannot do anything. If it wasn't internal you could use the new keyword on the method you're overriding (to hide the original implementation) when extending the class.

因为您不在同一个程序集中,所以您不能做任何事情。如果它不是内部的,您可以在扩展类时在要覆盖的方法上使用 new 关键字(以隐藏原始实现)。

In short: you are to be SOL.

简而言之:你要成为SOL。

The only thing i can think of you could do is write a proxy class, where one of your private fields is the class you'd want to extend and you implement all it's methods and proxy their calls. that way you can still customize output, but you'd have to get your class used, and considering it's marked internal, i'm not sure that's possible without some serious hacking.

我能想到的唯一一件事就是编写一个代理类,其中一个私有字段是您想要扩展的类,并且您实现它的所有方法并代理它们的调用。这样您仍然可以自定义输出,但是您必须使用您的类,并且考虑到它被标记为内部,我不确定如果没有一些严重的黑客攻击是可能的。

using System;
...
using System.Web.Script.Services

namespace MyGreatCompany.ScriptServices 
{
    public class MyScriptHandlerFactory /* implement all the interfaces */
    {
        private ScriptHandlerFactory internalFactory;
        public MyScriptHandlerFactory()
        {
            internalFactory = new ScriptHandlerFactory();
        }
        ...
    }
}

This couldmake what you want to accomplish possible, but it won't be pretty.

可以使您想要完成的事情成为可能,但它不会很漂亮。

回答by Rob Walker

I believe you can use Reflection to get around the access modifiers on a class, so perhaps you can use Reflection.Emit to generate a type that inherits from an internal type (but NOTthe sealed modifier), though I can't find an example of this online.

我相信你可以使用 Reflection 来绕过类上的访问修饰符,所以也许你可以使用 Reflection.Emit 来生成一个继承自内部类型(但不是密封修饰符)的类型,尽管我找不到一个例子这个网上。

This certainly works for accessing private members of classes, and probably for inheritance of non-sealed classes. But it doesn't help much if the target methods are not already marked virtual.

这当然适用于访问类的私有成员,并且可能适用于非密封类的继承。但是,如果目标方法尚未标记为虚拟,则无济于事。

回答by MichaelGG

It depends on the assembly. This could possibly violate some licensing (although its similar to some sort of static linking), and maybe even make deployment a nightmare, but you could consider:

这取决于装配。这可能会违反某些许可(尽管它类似于某种静态链接),甚至可能使部署成为一场噩梦,但您可以考虑:

  • Decompile and copy the code over to your own project; modify as needed
  • Recompile/patch the assembly and add an "InternalsVisibleToAttribute"
  • 反编译并将代码复制到您自己的项目中;根据需要修改
  • 重新编译/修补程序集并添加“InternalsVisibleToAttribute”