Ich habe eine abstrakte Klasse und möchte sie zu einer Klasse initialisieren, die sie erweitert.
Ich habe den Namen der untergeordneten Klassen als Zeichenfolge.
Außerdem ...
String childClassString;
MyAbstractClass myObject;
if (childClassString = "myExtenedObjectA")
myObject = new ExtenedObjectA();
if (childClassString = "myExtenedObjectB")
myObject = new ExtenedObjectB();
Wie kann ich das machen? Grundsätzlich, wie werde ich die if-Anweisungen hier los?
c#
reflection
polymorphism
ctrlShiftBryan
quelle
quelle
GetType
Dokumentation zu seinemtypeName
Parameter "Der Assembly-qualifizierte Name des Typs" angegeben ist, müssen Sie den Assembly-Namen nicht angeben. Wenn sich der Typ in der aufrufenden Assembly befindet, ist nur der für den Namespace qualifizierte Typname ausreichend.Ich glaube, das sollte funktionieren:
myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString);
Der
null
Parameter im ersten Parameter ist standardmäßig die aktuell ausgeführte Assembly. Weitere Informationen: MSDNbearbeiten: vergessen zu besetzen
MyAbstractClass
quelle
Ich hatte einige Schwierigkeiten, einige der Antworten hier zu implementieren, weil ich versuchte, ein Objekt aus einer anderen Assembly zu instanziieren (aber in derselben Lösung). Also dachte ich, ich würde posten, was ich für die Arbeit gefunden habe.
Erstens weist die
Activator.CreateInstance
Methode mehrere Überladungen auf. Wenn Sie nur aufrufenActivator.CreateInstance(Type.GetType("MyObj"))
, wird davon ausgegangen , dass das Objekt in der aktuellen Assembly definiert ist, und es wird a zurückgegebenMyObj
.Wenn Sie es wie in den Antworten hier empfohlen aufrufen
Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName)
, gibt es stattdessen ein zurückObjectHandle
, und Sie müssen es aufrufenUnwrap()
, um Ihr Objekt zu erhalten. Diese Überladung ist nützlich, wenn Sie versuchen, eine in einer anderen Assembly definierte Methode aufzurufen (Übrigens können Sie diese Überladung in der aktuellen Assembly verwenden, lassen Sie einfach denAssemblyName
Parameter null).Nun stellte ich fest, dass der obige Vorschlag,
typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedName
fürAssemblyName
den ich ihn verwenden sollte, tatsächlich Fehler verursachte, und ich konnte das nicht zum Laufen bringen. Ich würde bekommenSystem.IO.FileLoadException
(konnte Datei oder Baugruppe nicht laden ...).Was ich zur Arbeit gebracht habe, ist wie folgt:
var container = Activator.CreateInstance(@"AssemblyName",@"ParentNamespace.ChildNamespace.MyObject"); MyObject obj = (MyObject)container.Unwrap(); obj.DoStuff();
quelle