2008-10-13 16 views
9

Hay algo que quiero personalizar en System.Web.Script.Services.ScriptHandlerFactory y otras cosas de .NET dentro de una clase interna. Desafortunadamente, es una clase interna. ¿Qué opciones tengo al intentar personalizar un método en esta clase?¿Cómo se "anula" una clase interna en C#?

+0

Usted realmente no debería ya que el propietario de la clase ha marcado como interna (leer .. no se extienden desde que puede cambiar más tarde/Es trabajo en progreso/no es el mejor hasta ahora). Crea tu propia réplica de la clase y úsala si realmente debes hacerlo. – Gishu

Respuesta

6

Puede encontrar this recent article esclarecedor. Básicamente, dice que no puede anular nada marcado internal, y la fuente es tan autorizada como se pueda. Lo mejor que puedes esperar es un método de extensión.

+0

El blog de Eric Lippert es un excelente recurso, lo he seguido durante años. – Kev

5

La palabra clave interna significa que una unidad de código (clase, método, etc.) es "pública" para el ensamblaje en el que se encuentra, pero privada para cualquier otro ensamblaje.

Como no está en el mismo ensamblaje, no puede hacer nada. Si no fuera interno, podría usar la palabra clave nueva en el método que está sobrescribiendo (para ocultar la implementación original) al extender la clase.

En resumen: usted debe ser SOL.

Lo único que puedo pensar que podría hacer es escribir una clase de proxy, donde uno de sus campos privados es la clase que desea extender e implementar todos sus métodos y proxy de sus llamadas. de esa manera todavía puedes personalizar la salida, pero tendrías que utilizar tu clase, y considerando que está marcada internamente, no estoy seguro de que sea posible sin una piratería seria.

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(); 
     } 
     ... 
    } 
} 

Este podía hacer lo que se quiere lograr es posible, pero no va a ser bonito.

1

Creo que puede usar Reflection para evitar los modificadores de acceso en una clase, por lo que quizás pueda usar Reflection.Emit para generar un tipo que herede de un tipo interno (pero NOT el modificador sellado), aunque no puede encontrar un ejemplo de esto en línea.

Esto ciertamente funciona para acceder a miembros privados de clases, y probablemente por herencia de clases no selladas. Pero no ayuda mucho si los métodos de destino aún no están marcados como virtuales.

+0

También probablemente solo funcione cuando se ejecuta con plena confianza. Cualquier contexto que requiera verificación va a fallar cuando viola el control de acceso. –

+3

Este enfoque tampoco funciona, con una excepción como System.TypeLoadException: Method 'MyOverridingMethod' en el tipo 'MyClass' del ensamblado 'MyAssembly, Version = 0.0.0.0, Culture = neutral, PublicKeyToken = null' está anulando un método que no es visible desde esa asamblea. –

0

Depende del montaje. Esto posiblemente podría violar algunas licencias (aunque su similar a algún tipo de vinculación estática), y tal vez incluso hacer despliegue de una pesadilla, pero se puede considerar:

  • Descompilar y copiar el código a través de su propio proyecto; modificar según sea necesario
  • recompilación/parchear el montaje y añadir una "InternalsVisibleToAttribute"
Cuestiones relacionadas