Istanziazione della class interna con il costruttore privato

Sto cercando di usare la riflessione per creare un’istanza di una class. Ma è sigillato internamente e ha un costruttore privato. Mi chiedo come posso inizializzarlo e come parte della struttura, posso solo usare la riflessione per estrarlo?

internal sealed class ABC { private ABC(string password){} public static ABC Create(string password){}; } 

Aggiunto: System.ServiceModel.Channels.SelfSignedCertificate è la class interna che sto tentando di utilizzare

Prima di tutto, il fatto stesso che sia interno significa che non dovresti fare quello che vuoi fare.

Dovresti seriamente cercare di trovare un percorso alternativo a ciò che vuoi realizzare.

Sfortunatamente, non ci dici cosa vuoi realizzare, solo il prossimo passo che pensi di voler fare, quindi è quello con cui posso aiutarti.

Questo codice funzionerà e accede al metodo statico pubblico:

 Type t = typeof(SomeOtherTypeInSameAssembly) .Assembly.GetType("ClassLibrary1.ABC"); MethodInfo method = t.GetMethod("Create", BindingFlags.Public | BindingFlags.Static, null, new Type[] { typeof(String) }, new ParameterModifier[0]); Object o = method.Invoke(null, new Object[] { "test" }); 

Nota che questo si basa sull’avere accesso ad un altro tipo nello stesso assembly, che è pubblico. Se non lo hai, devi ottenere l’object Assembly che contiene il tipo.

EDIT: Non avevo notato che hai menzionato che il tipo che stai cercando di inizializzare fa parte del framework .NET. Ho pensato che fosse uno dei tuoi tipi, appena citato da altrove.

Vi esorto caldamente a non tentare di farlo . Microsoft è perfettamente in grado di modificare o rimuovere le classi interne tra le versioni di framework: il tuo codice sarà incredibilmente fragile se ti affidi a dettagli di implementazione come questo.

Cambia il tuo design per evitare di doverlo fare.


Risposta originale:

Sì, dovresti usare il riflesso – come questo:

 using System; using System.Reflection; internal sealed class ABC { private ABC(string password) { Console.WriteLine("Constructor called"); } } public class Test { static void Main() { ConstructorInfo ctor = typeof(ABC).GetConstructors (BindingFlags.Instance | BindingFlags.NonPublic)[0]; ABC abc = (ABC) ctor.Invoke(new object[] { "test" }); } } 

Si noti che la violazione dei modificatori di accesso in questo modo richiede l’authorization ReflectionPermissionFlag.MemberAccess . Se sai che ci sarà un metodo statico chiamato Create , è meglio invocarlo tramite riflessione:

 using System; using System.Reflection; internal sealed class ABC { private ABC(string password) { Console.WriteLine("Constructor called"); } public static ABC Create(string password) { return new ABC(password); } } public class Test { static void Main() { MethodInfo method = typeof(ABC).GetMethod("Create", BindingFlags.Static | BindingFlags.Public); ABC abc = (ABC) method.Invoke(null, new object[]{"test"}); } } 

Se è internal a un assembly che non è tuo e il costruttore è contrassegnato come private , l’autore dell’assembly sta tentando molto duramente di impedirti di creare l’object.

Il seguito è davvero malvagio poiché ti affidi a classi e metodi non pubblici che potrebbero cambiare su di te senza preavviso.

Aggiunto: System.ServiceModel.Channels.SelfSignedCertificate è la class internal che sto tentando di utilizzare

Non farlo . Il quadro potrebbe cambiare sotto di te in un batter d’occhio rovinando il tuo codice e tutto il tuo duro lavoro.

Detto questo, puoi fare questo:

 MethodInfo method = Type.GetType(assemblyQualifiedName).GetMethod("Create"); ABC o = (ABC)method.Invoke(null, new[] { "test" }); 

Questo richiama il metodo static Create . Un’altra opzione è

 MethodInfo method = Type.GetType(assemblyQualifiedName).GetConstructor( BindingFlags.NonPublic | BindingFlags.Instance, null, new[] { typeof(string) }, null ); ABC o = (ABC)method.Invoke(new[] { "test" }); 

che usa reflection per caricare il costruttore che accetta una string come parametro.

Un modo semplice per ottenere il nome qualificato dell’assemblato è

 string name = typeof(somePublicType).Assembly.GetType("Namespace.ABC"); 

dove somePublicType è un tipo pubblico e nello stesso assembly di ABC .

Non è ansible creare istanze di classi con costruttori privati ​​a meno che non si tratti di una class nidificata.

http://msdn.microsoft.com/en-us/library/kcfb85a6%28VS.71%29.aspx

Usa la class Activator per istanziarla

 Activator.CreateInstance(myType, true);