J'ai une classe abstraite et je veux l'initier à une classe qui la prolonge.
J'ai le nom des classes enfants sous forme de chaîne.
Mis-à-part...
String childClassString;
MyAbstractClass myObject;
if (childClassString = "myExtenedObjectA")
myObject = new ExtenedObjectA();
if (childClassString = "myExtenedObjectB")
myObject = new ExtenedObjectB();
Comment puis-je faire ceci? Fondamentalement, comment puis-je me débarrasser des instructions if ici?
Regardez Activator.CreateInstance ().
myObject = (MyAbstractClass)Activator.CreateInstance("AssemblyName", "TypeName");
ou
var type = Type.GetType("MyFullyQualifiedTypeName");
var myObject = (MyAbstractClass)Activator.CreateInstance(type);
Je pense que cela devrait fonctionner:
myObject = (MyAbstractClass)Activator.CreateInstance(null, childClassString);
Le null
dans le premier paramètre est par défaut l'assembly en cours d'exécution. Pour plus de référence: MSDN
edit: oublié de caster en MyAbstractClass
J'ai eu quelques difficultés à mettre en œuvre certaines des réponses ici parce que j'essayais d'instancier un objet à partir d'un assembly différent (mais dans la même solution). J'ai donc pensé publier ce que j'ai trouvé efficace.
Premièrement, la méthode Activator.CreateInstance
A plusieurs surcharges. Si vous appelez simplement Activator.CreateInstance(Type.GetType("MyObj"))
, cela suppose que l'objet est défini dans l'assembly en cours et renvoie un MyObj
.
Si vous l'appelez comme recommandé dans les réponses ici: Activator.CreateInstance(string AssemblyName, string FullyQualifiedObjectName)
, alors il renvoie à la place un ObjectHandle
, et vous devez appeler Unwrap()
dessus pour obtenir votre objet. Cette surcharge est utile lorsque vous essayez d'appeler une méthode définie dans un assembly différent (BTW, vous pouvez utiliser cette surcharge dans l'assembly actuel, laissez simplement le paramètre AssemblyName
null).
Maintenant, j'ai trouvé que la suggestion ci-dessus d'utiliser typeof(ParentNamespace.ChildNamespace.MyObject).AssemblyQualifiedName
pour AssemblyName
m'a en fait donné des erreurs, et je n'ai pas pu faire fonctionner cela. J'obtiendrais System.IO.FileLoadException
(Impossible de charger le fichier ou l'assemblage ...).
Ce que je suis arrivé au travail est le suivant:
var container = Activator.CreateInstance(@"AssemblyName",@"ParentNamespace.ChildNamespace.MyObject");
MyObject obj = (MyObject)container.Unwrap();
obj.DoStuff();