On ne connaît pas toujours le Type
d'un objet à la compilation, mais on peut avoir besoin de créer une instance de ce Type
. Comment obtenir une nouvelle instance d'objet à partir d'un Type
?
La classe Activator
de l'espace de nom racine System
est assez puissante.
Il y a beaucoup de surcharges pour passer des paramètres au constructeur et autres. Consultez la documentation à l'adresse suivante :
ou (nouveau chemin)
Voici quelques exemples simples :
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);
ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");
Une façon de résoudre ce problème est d'essayer d'appeler le constructeur sans paramètre du Type :
public static object GetNewObject(Type t)
{
try
{
return t.GetConstructor(new Type[] { }).Invoke(new object[] { });
}
catch
{
return null;
}
}
Voici la même approche, contenue dans une méthode générique :
public static T GetNewObject<T>()
{
try
{
return (T)typeof(T).GetConstructor(new Type[] { }).Invoke(new object[] { });
}
catch
{
return default(T);
}
}
Si c'est pour quelque chose qui sera appelé souvent dans une instance d'application, il est beaucoup plus rapide de compiler et de mettre en cache le code dynamique plutôt que d'utiliser l'activateur ou ConstructorInfo.Invoke()
. Deux options faciles pour la compilation dynamique sont les [Expressions Linq][1] compilées ou quelques simples [opcodes IL
et DynamicMethod
][2]. Dans un cas comme dans l'autre, la différence est énorme lorsque vous commencez à entrer dans des boucles serrées ou des appels multiples.
[1] : http://rogeralsing.com/2008/02/28/linq-expressions-creating-objects/ [2] : http://web.archive.org/web/20140926050502/http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx