Gibt es eine Möglichkeit, eine Instanz einer Klasse basierend auf der Tatsache zu erstellen, dass ich den Namen der Klasse zur Laufzeit kenne. Grundsätzlich hätte ich den Namen der Klasse in einer Zeichenfolge.
Gibt es eine Möglichkeit, eine Instanz einer Klasse basierend auf der Tatsache zu erstellen, dass ich den Namen der Klasse zur Laufzeit kenne. Grundsätzlich hätte ich den Namen der Klasse in einer Zeichenfolge.
Antworten:
Schauen Sie sich die Activator.CreateInstance- Methode an.
var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
Es ist ziemlich einfach. Angenommen, Ihr Klassenname ist Car
und der Namespace ist Vehicles
, und übergeben Sie den Parameter, Vehicles.Car
der ein Objekt vom Typ zurückgibt Car
. Auf diese Weise können Sie jede Instanz einer beliebigen Klasse dynamisch erstellen.
public object GetInstance(string strFullyQualifiedName)
{
Type t = Type.GetType(strFullyQualifiedName);
return Activator.CreateInstance(t);
}
Wenn sich Ihr vollständig qualifizierter Name (dh Vehicles.Car
in diesem Fall) in einer anderen Assembly befindet, ist der NameType.GetType
null. In solchen Fällen haben Sie eine Schleife durch alle Baugruppen und finden die Type
. Dafür können Sie den folgenden Code verwenden
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;
}
Wenn Sie nun einen parametrisierten Konstruktor aufrufen möchten, gehen Sie wie folgt vor
Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type
anstatt
Activator.CreateInstance(t);
dynamic
Code verwenden - siehe stackoverflow.com/a/2690661/904521 )
strFullyQualifiedName
mit str
, fullyQualifiedName
wird die Arbeit machen.
str
wird als Teil der Namenskonvention für Variablen verwendet. Bestimmte Organisationen und Projekte bestehen darauf, dies zu befolgen, daher habe ich verwendet. Wenn Sie in bestimmten Organisationen / Projekten gearbeitet hätten, wissen Sie dies. Wie Sie sagten, auch ohne str
wird es den Job machen :) @MehdiDehghani
Ich habe diese Methode erfolgreich angewendet:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
Sie müssen das zurückgegebene Objekt in den gewünschten Objekttyp umwandeln.
Wahrscheinlich hätte meine Frage spezifischer sein sollen. Ich kenne tatsächlich eine Basisklasse für den String, also löste ich sie durch:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Die Activator.CreateInstance-Klasse verfügt über verschiedene Methoden, um dasselbe auf unterschiedliche Weise zu erreichen. Ich hätte es auf ein Objekt werfen können, aber das Obige ist für meine Situation am nützlichsten.
Ich weiß, dass ich zu spät zum Spiel komme ... aber die Lösung, nach der Sie suchen, könnte die Kombination der oben genannten sein und die Verwendung einer Schnittstelle zum Definieren öffentlich zugänglicher Aspekte Ihrer Objekte.
Wenn dann alle Ihre Klassen, die auf diese Weise generiert würden, diese Schnittstelle implementieren, können Sie sie einfach als Schnittstellentyp umwandeln und mit dem resultierenden Objekt arbeiten.
Um eine Instanz einer Klasse aus einem anderen Projekt in der Lösung zu erstellen, können Sie die Assembly mit dem Namen einer beliebigen Klasse (z. B. BaseEntity) anzeigen lassen und eine neue Instanz erstellen:
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
Wenn Sie beispielsweise Werte verschiedener Typen in einem Datenbankfeld (als Zeichenfolge gespeichert) speichern und ein anderes Feld mit dem Typnamen (dh Zeichenfolge, bool, int, MyClass) haben, können Sie aus diesen Felddaten möglicherweise Erstellen Sie mit dem obigen Code eine Klasse eines beliebigen Typs und füllen Sie sie mit dem Wert aus dem ersten Feld. Dies hängt natürlich vom Typ ab, den Sie speichern, und verfügt über eine Methode zum Parsen von Zeichenfolgen in den richtigen Typ. Ich habe dies oft verwendet, um Benutzereinstellungen in einer Datenbank zu speichern.
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Warum willst du so einen Code schreiben? Wenn eine Klasse 'ReportClass' verfügbar ist, können Sie diese wie unten gezeigt direkt instanziieren.
ReportClass report = new ReportClass();
Der Code ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
wird verwendet, wenn Sie nicht über die erforderliche Klasse verfügen, aber eine Methode dynamisch instanziieren und / oder aufrufen möchten.
Ich meine, es ist nützlich, wenn Sie die Assembly kennen, aber während Sie den Code schreiben, steht Ihnen die Klasse nicht zur ReportClass
Verfügung.