2011-12-13 18 views
5

¿Hay alguna forma de de heredar de una clase abstracta interna en una clase de tiempo de ejecución generada dinámicamente (como por reflexión) con .NET Framework 4.0?Heredar dinámicamente de la clase interna a través de la reflexión

+2

Eso es imposible. –

+4

Tal vez algunos antecedentes sobre lo que está tratando de lograr y por qué ayudaría a obtener una respuesta útil. –

+0

No veo por qué esta pregunta se cerró como "no es una pregunta real". Creo que está claro lo que el OP quería preguntar. Admito que es realmente bastante "perverso" (como escribió John Hanna en su respuesta), pero en realidad tengo un problema (una clase que previamente era pública, se hizo interna de una versión a otra del marco en el que dependemos), que podemos "resolver" heredando de una clase interna, si es posible ... – pholpar

Respuesta

18

Fuera de un sentido general de perversidad frente a cosas que no deberían ser posibles, lo intenté a ver cómo Me gustaría tratar de crear una clase heredada de System.CurrentSystemTimeZone (una clase interna en mscorlib). Te permite llegar a crear un TypeBuilder, pero cuando llamas al CreateType arroja un TypeLoadException con el mensaje "Acceso denegado: 'System.CurrentSystemTimeZone'."

Un poco más de violín me llevó a la conclusión de que se podía crear un ensamblaje de forma dinámica que tenía el nombre fuerte que lo identificaba como un ensamblaje amigo del ensamblaje en el que se define el tipo interno. Pero entonces, en ese caso, podría simplemente codificar class Foo : CurrentSystemTimeZone de todos modos, sin ningún engaño.

De todos modos, el código por lo que la línea que lanza está por debajo, por si alguien está en el estado de ánimo para intentar alguna variante aún más perversa en la idea, y quiere un punto de partida:

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

No puede. Puede usar tipos que no son públicos usando Assembly.GetType(), pero no puede heredar de ellos. Jon Skeet explains in this article por qué generalmente es una mala idea acceder a miembros no públicos, y responde su pregunta más en profundidad que yo.

+1

Puede acceder a los tipos internos a través de Reflection. –

+0

@YuriyFaktorovich Puede acceder a ellos, pero hasta donde yo sé, no puede heredar de ellos. – aevitas

+0

En realidad estoy adivinando que puede usar el ILGenerator, pero aún no lo he probado. –

5

Claro que puede y no necesita reflexión para eso. La clase heredada solo necesita estar en el mismo ensamblaje :)

También puede configurar amistad entre conjuntos: http://msdn.microsoft.com/en-us/library/0tke9fxk%28v=VS.100%29.aspx, que permitiría el acceso a las clases internas de un ensamblaje. Este enfoque a veces es útil para crear ensamblajes de Prueba de unidad que necesitan acceso interno a conjuntos probados

+0

+1 para el valor de entretenimiento. Pero uno no puede hacer amistad a través de la reflexión, por lo que no es realmente útil para EOG. –

+0

Interpreto "ex" como "por ejemplo", por lo que la reflexión puede no ser un requisito difícil. – surfen

+0

Buen punto ... Supongo que @EOG debería obtener -1 para el título que no coincide con la pregunta ... pero creo que -2 es demasiado para esta pregunta. –

Cuestiones relacionadas