it-swarm.com.de

Erstellen Sie eine Instanz einer Klasse aus einer Zeichenfolge

Gibt es eine Möglichkeit, eine Instanz einer Klasse zu erstellen, die auf der Tatsache basiert, dass ich zur Laufzeit den Namen der Klasse kenne? Grundsätzlich hätte ich den Namen der Klasse in einem String.

189
PeteT

Sehen Sie sich die Methode Activator.CreateInstance an.

147
Matt Hamilton

Es ist ziemlich einfach. Angenommen, Ihr Klassenname ist Car und der Namespace ist Vehicles, und übergeben Sie den Parameter als Vehicles.Car, der ein Objekt vom Typ Car zurückgibt. Auf diese Weise können Sie jede Instanz einer Klasse dynamisch erstellen.

public object GetInstance(string strFullyQualifiedName)
{         
     Type t = Type.GetType(strFullyQualifiedName); 
     return  Activator.CreateInstance(t);         
}

Befindet sich Ihr Fully Qualified Name (dh in diesem Fall Vehicles.Car) in einer anderen Assembly, ist Type.GetType null. In solchen Fällen müssen Sie alle Assemblys durchlaufen und die Type finden. Dafür können Sie den untenstehenden 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);
54
Sarath Avanavu

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.

52
Ray Li

Wahrscheinlich hätte meine Frage genauer sein sollen. Ich kenne eigentlich eine Basisklasse für den String, der so gelöst wurde:

ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));

Die Activator.CreateInstance-Klasse verfügt über verschiedene Methoden, um auf unterschiedliche Weise dasselbe zu erreichen. Ich hätte es in ein Objekt verwandeln können, aber das oben genannte ist für meine Situation am nützlichsten.

19
PeteT

Ich weiß, ich bin spät dran ... aber die Lösung, die Sie suchen, könnte die Kombination der obigen sein und die Verwendung einer Schnittstelle zum Definieren Ihrer Objekte für öffentlich zugängliche Aspekte.

Wenn dann alle Klassen, die auf diese Weise generiert werden, diese Schnittstelle implementieren, können Sie einfach als Schnittstellentyp fungieren und mit dem resultierenden Objekt arbeiten.

4
Denny

Wenn Sie beispielsweise Werte verschiedener Typen in einem Datenbankfeld speichern (als String gespeichert) und ein anderes Feld mit dem Typnamen haben (dh String, Bool, Int, MyClass), dann könnten Sie aus diesen Felddaten Erstellen Sie mit dem obigen Code eine Klasse eines beliebigen Typs und füllen Sie sie mit dem Wert aus dem ersten Feld auf. Dies hängt natürlich von dem Typ ab, den Sie speichern, und verfügt über eine Methode, um Zeichenfolgen in den richtigen Typ zu analysieren. Ich habe dies oft verwendet, um Benutzereinstellungen in einer Datenbank zu speichern.

3
Greg Osborne

Sie scheinen die Lösung beschrieben zu haben, die Sie implementieren möchten, nicht aber das Problem, das Sie lösen möchten. 

Vielleicht versuchen Sie etwas mit Erweiterbarkeit zu tun. In diesem Fall schlage ich vor, das Managed Extensibility Framework zu besuchen.

3
Jay Bazuzi

Um eine Instanz einer Klasse aus einem anderen Projekt in der Lösung zu erstellen, können Sie die Assembly durch den 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");
0
juanpe