2008-09-30 17 views
15

Antes de que comiences a dispararme, NO estoy buscando hacer esto, pero alguien en another post dijo que era posible. ¿Como es posible? Nunca he oído hablar de heredar de nada usando la reflexión. Pero he visto algunas cosas extrañas ...¿Cómo se puede heredar de una clase sellada usando la reflexión en .Net?

+1

Mmhh Creo que aquí es cuando viene la reputación de utilidad. El que respondió esa pregunta tiene 19 de rep (a partir del 30 de septiembre). Es probable que no sepa de lo que está hablando.Por otro lado, te tenemos a ti, diciendo que no es posible. Entonces, debes confiar en ti mismo en este caso. – OscarRyz

+0

:) Kilhoffer (2459) vs. dalle.myopenid.com (19) – OscarRyz

+0

lol, divertido, Oscar! – user18931

Respuesta

13

Sin funciones virtuales que sobrescribir, no tiene mucho sentido crear subclases de una clase sellada.

Si intenta escribir una clase sellada con una función virtual en ella, se obtiene el siguiente error de compilación:

// error CS0549: 'Seal.GetName()' is a new virtual member in sealed class 'Seal' 

Sin embargo, puede obtener funciones virtuales en clases cerradas que declaró en una clase base (como este),

public abstract class Animal 
{ 
    private readonly string m_name; 

    public virtual string GetName() { return m_name; } 

    public Animal(string name) 
    { m_name = name; } 
} 

public sealed class Seal : Animal 
{ 
    public Seal(string name) : base(name) {} 
} 

el problema sigue siendo, sin embargo, no puedo ver cómo se puede colar a través del compilador para permitir que se declara una subclase. Traté de usar IronRuby (ruby es el más hackeo de todos los lenguajes de hackety) pero incluso no me lo permitió.

La parte "sellada" está incrustada en el MSIL, por lo que supongo que el CLR en realidad lo hace cumplir. Tendría que cargar el código, desmontarlo, quitar el bit 'sellado', volver a montarlo y cargar la nueva versión.

+1

he visto un ejemplo en el que alguien parcheado el CLR. Haz una búsqueda en Dinis Cruz y OWASP y deberías encontrarlo – alexmac

+1

crikey. Eso es hardcore –

+8

Los defectos de seguridad donde el atacante es más fuerte que el sistema de seguridad no son fallas. "Incursioné en tu edificio reemplazando todos los bloqueos por otros idénticos, excepto que responden a los comandos Bluetooth desde mi teléfono celular". ¡El ataque con Bluetooth es irrelevante en comparación con la eliminación de mis bloqueos! –

1

Se FUERZA (aumentaría el tamaño si pudiera). Según los chicos de freenode, implicaría modificar el código de byte, usar Reflection.Emit, y darle al JIT un nuevo conjunto de código byte.

No es que yo CONOZCA cómo ... era lo que pensaban.

+0

Esa es la única forma en que tendría sentido. Por el trabajo involucrado, ¿cómo demonios podría alguien justificar eso? Es una locura – Kilhoffer

+1

NO PUEDE justificarlo legítimamente. – MagicKat

+1

Si hiciera eso, entonces no sería en realidad se deriva de una clase sellada ... que estaría jodiendo con la clase para quitar el sellado, a continuación, haciendo una derivación normal. Eso puede ser una solución válida a su problema, pero estoy simplemente diciendo, no se deriva de una clase cerrada más :-) –

1

El otro póster puede haber estado pensando más en las líneas de Reflection.Emit en lugar de las API de Reflection de solo lectura más habituales.

Sin embargo, todavía no es posible (al menos según this article). Pero ciertamente es posible atornillar algo con Reflection. Emit que no estén atrapados hasta que intentes ejecutar realmente el código emitido.

8

Lo siento por publicar suposiciones incorrectas en el otro hilo, no pude recordar correctamente. Usando el siguiente ejemplo, usando Reflection.Emit, muestra cómo derivar de otra clase, pero falla en tiempo de ejecución al lanzar una TypeLoadException.

sealed class Sealed 
{ 
    public int x; 
    public int y; 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     AppDomain ad = Thread.GetDomain(); 
     AssemblyName an = new AssemblyName(); 
     an.Name = "MyAssembly"; 
     AssemblyBuilder ab = ad.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); 
     ModuleBuilder mb = ab.DefineDynamicModule("MyModule"); 
     TypeBuilder tb = mb.DefineType("MyType", TypeAttributes.Class, typeof(Sealed)); 

     // Following throws TypeLoadException: Could not load type 'MyType' from 
     // assembly 'MyAssembly' because the parent type is sealed. 
     Type t = tb.CreateType(); 
    } 
} 
+2

Si no puede cargar la cosa que haya generado, no creo que cuenta como la creación de una clase derivada ... Después de todo, se puede crear todo tipo de cosas en mal estado utilizando 'Reflection.Emit', pero eso no lo hace para que esas cosas sean de alguna manera ahora válidas. –

+4

@OrionEdwards: Eso es lo que escribí en esta respuesta. No funcionará, y fui incorrecta en mis suposiciones previas. – dalle

-2

Crear una nueva clase llamada GenericKeyValueBase

poner esto en él

public class GenericKeyValueBase<TKey,TValue> 
    { 
     public TKey Key; 
     public TValue Value; 

     public GenericKeyValueBase(TKey ItemKey, TValue ItemValue) 
     { 
      Key = ItemKey; 
      Value = ItemValue; 
     } 
    } 

Y heredar de que además se puede añadir métodos de extensión adicionales para Agregar/Quitar (AddAt y RemoveAt) a su nueva clase derivada (y convertirla en una colección/diccionario) si te sientes realmente genial.

Un ejemplo implementació sencillo en el que se utilizaría un System.Collections.Generic.KeyValuePair normal para una base, pero en su lugar puede utilizar el código anterior

class GenericCookieItem<TCookieKey, TCookieValue> : GenericKeyValueBase<TCookieKey,TCookieValue> 
    { 
     public GenericCookieItem(TCookieKey KeyValue, TCookieValue ItemValue) : base(KeyValue, ItemValue) 
     { 
     } 
    } 
+0

No veo cómo se relaciona esto con la herencia de las clases selladas. – Abel

+0

Las clases selladas que implementan lo anterior ahora tendrían la capacidad de ser aumentadas con objetos TCookieKey/Value para una pseudo extensibilidad. El método incluso podría estar oculto en la clase base ... – Jay

Cuestiones relacionadas