Esiste un modo per ereditare da una classe astratta interna in una classe di runtime generata dinamicamente (come tramite riflessione) utilizzando .NET Framework 4.0?Assegna dinamicamente dalla classe interna tramite la riflessione
risposta
Fuori da un senso generale di perversità di fronte a cose che non dovrebbero essere possibili, ho fatto un tentativo di vedere come lontano proverei a creare una classe ereditata da System.CurrentSystemTimeZone
(una classe interna in mscorlib). Si arriva fino alla creazione di un TypeBuilder
ma quando si chiama CreateType
si getta un TypeLoadException
con il messaggio "Accesso negato: 'System.CurrentSystemTimeZone'."
Un po 'più di giocherellando mi ha portato a concludere che è possibile creare un assembly dinamicamente con il nome sicuro che lo identifica come un assembly amico dell'assieme in cui è definito il tipo interno. Ma allora, in quel caso potresti semplicemente scrivere il codice class Foo : CurrentSystemTimeZone
, senza lasciare trucchi.
In ogni caso, il codice per quanto riguarda la linea che getta è al di sotto, nel caso in cui uno è in vena di provare qualche variante ancora più perversa l'idea, e vuole un punto di partenza:
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();
}
}
}
Non è possibile. Puoi usare tipi che non sono pubblici usando Assembly.GetType()
, ma non puoi ereditarli. Jon Skeet explains in this article perché in genere è una cattiva idea accedere ai membri non pubblici e rispondere alla tua domanda in modo più approfondito di quanto avrei potuto.
È possibile accedere a tipi interni tramite Reflection. –
@YuriyFaktorovich Puoi accedervi, ma per quanto ne so non puoi ereditarne. – aevitas
In realtà suppongo che tu possa utilizzare ILGenerator, ma non l'ho ancora provato. –
Certo che puoi e non hai bisogno di riflettere per quello. La classe ereditata solo bisogno di essere nello stesso assieme :)
È anche possibile impostare amicizia tra assiemi: http://msdn.microsoft.com/en-us/library/0tke9fxk%28v=VS.100%29.aspx, che consentirebbe l'accesso alle classi interne di un complesso. Questo approccio è a volte utile nella creazione di assemblaggi di Unit-Test che richiedono l'accesso interno agli assembly testati
+1 per il valore di intrattenimento. Ma non si può fare amicizia tramite la riflessione, quindi non è veramente utile per EOG. –
Interpreto "ex". come "ad esempio", quindi la riflessione potrebbe non essere un requisito difficile. – surfen
Buon punto ... Immagino che @EOG debba ottenere -1 per il titolo che non corrisponde alla domanda ... ma penso che -2 sia troppo per questa domanda. –
- 1. Come istanziare la classe interna con la riflessione in Java?
- 2. pitone creare dinamicamente classe con classe interna
- 3. C# derivato dalla classe derivata alla classe base di eccezione tramite la riflessione
- 4. Typescript: Assegna dinamicamente le proprietà alla classe
- 5. Chiamare la funzione di classe esterna dalla classe interna
- 6. Istanziare dinamicamente una classe tramite la variabile
- 7. Accesso alle variabili dalla classe interna
- 8. Risultati riflessione cache (proprietà classe)
- 9. classe Annotate con classe interna
- 10. Ottieni l'attributo dalla classe generata dinamicamente
- 11. Comportamento membro diverso della classe interna se la classe interna estende la classe esterna?
- 12. Come ottengo le costanti definite dalla classe del modulo di Ruby tramite riflessione?
- 13. Classe interna classe Golang
- 14. Come impedire l'accesso tramite riflessione?
- 15. un'istanza di un costruttore con parametri in una classe interna con la riflessione
- 16. Subclassing classe interna da esterno Classe contro altra classe interna
- 17. Trova proprietà nullable tramite la riflessione
- 18. generare dinamicamente proprietà getter/setter attraverso la riflessione o simili
- 19. Come si assegna dinamicamente una matrice?
- 20. Utilizzo della classe interna BatteryStatsImpl tramite Reflection in android
- 21. Come accedere alla classe Java interna statica tramite l'interoperabilità Clojure?
- 22. La classe interna privata sintetizza la classe anonima inaspettata
- 23. Impossibile importare la classe interna statica?
- 24. Assegna classe derivata da classe base
- 25. Perché ottengo i metodi della classe base tramite riflessione quando la sottoclasse sovrascrive?
- 26. Accesso alle variabili private in Java tramite la riflessione
- 27. È una classe interna
- 28. Proteggi le variabili finali dalla riflessione
- 29. Classe Struttura interna
- 30. testare una classe interna
Ecco non possibile. –
Forse un po 'di background su cosa stai cercando di ottenere e perché sarebbe utile ottenere una risposta utile. –
Non vedo perché questa domanda è stata chiusa come "non è una vera domanda". Penso che sia chiaro cosa volesse chiedere l'OP. Ammetto che è davvero piuttosto "perverso" (come ha scritto @John Hanna nella sua risposta), ma in realtà ho un problema (una classe che in precedenza era pubblica, è stata resa interna da una versione all'altra del framework da cui dipende), che possiamo "risolvere" ereditando da una classe interna, se fosse possibile ... – pholpar