你如何“覆盖”C#中的内部类?

时间:2022-09-02 09:21:11

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内容中自定义。不幸的是,这是一个内部课程。尝试自定义此类中的方法时,我有哪些选项?

4 个解决方案

#1


8  

You might find this recent article enlightening. 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.

您可能会发现这篇近期文章很有启发性。基本上,它表示你不能覆盖任何标记为内部的东西,并且源代码就像它获得的权威一样。你可以期待的最好的是一种扩展方法。

#2


6  

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.

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

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 could make what you want to accomplish possible, but it won't be pretty.

这可以使您想要实现的目标成为可能,但它不会很漂亮。

#3


1  

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 NOT the 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.

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

#4


0  

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”

#1


8  

You might find this recent article enlightening. 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.

您可能会发现这篇近期文章很有启发性。基本上,它表示你不能覆盖任何标记为内部的东西,并且源代码就像它获得的权威一样。你可以期待的最好的是一种扩展方法。

#2


6  

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.

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

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 could make what you want to accomplish possible, but it won't be pretty.

这可以使您想要实现的目标成为可能,但它不会很漂亮。

#3


1  

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 NOT the 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.

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

#4


0  

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”