Esiste un modo per creare un'istanza di una classe in base al fatto che conosco il nome della classe in fase di esecuzione. Fondamentalmente avrei il nome della classe in una stringa.
Esiste un modo per creare un'istanza di una classe in base al fatto che conosco il nome della classe in fase di esecuzione. Fondamentalmente avrei il nome della classe in una stringa.
Risposte:
Dai un'occhiata al metodo Activator.CreateInstance .
var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
È piuttosto semplice. Supponiamo che il tuo nome classe sia Car
e lo spazio dei nomi sia Vehicles
, quindi passa il parametro come Vehicles.Car
che restituisce l'oggetto di tipo Car
. In questo modo puoi creare dinamicamente qualsiasi istanza di qualsiasi classe.
public object GetInstance(string strFullyQualifiedName)
{
Type t = Type.GetType(strFullyQualifiedName);
return Activator.CreateInstance(t);
}
Se il tuo nome completo (ovvero, Vehicles.Car
in questo caso) si trova in un altro assembly, Type.GetType
sarà nullo. In tali casi, è necessario scorrere tutti gli assiemi e trovare il file Type
. Per questo puoi usare il codice qui sotto
public object GetInstance(string strFullyQualifiedName)
{
Type type = Type.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
type = asm.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
}
return null;
}
Ora, se vuoi chiamare un costruttore con parametri, procedi come segue
Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type
invece di
Activator.CreateInstance(t);
dynamic
codice - vedi stackoverflow.com/a/2690661/904521 )
strFullyQualifiedName
con str
, fullyQualifiedName
farà il lavoro.
str
viene utilizzata come parte della convenzione di denominazione per le variabili. Alcune organizzazioni e progetti insistono nel seguire questo, quindi ho usato. Se avessi lavorato in determinati oraganizzazioni / progetti, lo saprai. Come hai detto senza str
, farà anche il lavoro :) @MehdiDehghani
Ho usato questo metodo con successo:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
Dovrai trasmettere l'oggetto restituito al tipo di oggetto desiderato.
Probabilmente la mia domanda avrebbe dovuto essere più specifica. In realtà conosco una classe base per la stringa così risolta da:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
La classe Activator.CreateInstance ha vari metodi per ottenere la stessa cosa in modi diversi. Avrei potuto lanciarlo su un oggetto ma quanto sopra è di grande utilità per la mia situazione.
So di essere in ritardo al gioco ... ma la soluzione che stai cercando potrebbe essere la combinazione di quanto sopra e l'utilizzo di un'interfaccia per definire gli aspetti accessibili al pubblico dei tuoi oggetti.
Quindi, se tutte le classi che verrebbero generate in questo modo implementano tale interfaccia, puoi semplicemente eseguire il cast come tipo di interfaccia e lavorare con l'oggetto risultante.
Per creare un'istanza di una classe da un altro progetto nella soluzione, è possibile ottenere l'assemblaggio indicato dal nome di qualsiasi classe (ad esempio BaseEntity) e creare una nuova istanza:
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
Ad esempio, se si memorizzano valori di vari tipi in un campo del database (memorizzato come stringa) e si dispone di un altro campo con il nome del tipo (ovvero String, bool, int, MyClass), quindi dai dati di quel campo, è possibile, presumibilmente, crea una classe di qualsiasi tipo usando il codice sopra e popolala con il valore dal primo campo. Questo ovviamente dipende dal tipo che stai memorizzando con un metodo per analizzare le stringhe nel tipo corretto. L'ho usato molte volte per memorizzare le impostazioni delle preferenze dell'utente in un database.
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
perché vuoi scrivere un codice come questo? Se è disponibile una classe "ReportClass", è possibile creare un'istanza direttamente come mostrato di seguito.
ReportClass report = new ReportClass();
Il codice ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
viene utilizzato quando non si dispone della classe necessaria disponibile, ma si desidera creare un'istanza e / o invocare un metodo in modo dinamico.
Voglio dire, è utile quando conosci l'assembly ma mentre scrivi il codice non hai la classe ReportClass
disponibile.