On ne sait pas toujours Type
d'un objet au moment de la compilation, mais il peut être nécessaire de créer une instance de l'objet Type
.
Comment obtenir une nouvelle instance d'objet à partir d'un fichier Type
?
On ne sait pas toujours Type
d'un objet au moment de la compilation, mais il peut être nécessaire de créer une instance de l'objet Type
.
Comment obtenir une nouvelle instance d'objet à partir d'un fichier Type
?
Le site Activator
au sein de la classe Root System
est assez puissant.
Il y a beaucoup de surcharges pour passer des paramètres au constructeur et autres. Consultez la documentation à l'adresse suivante :
http://msdn.microsoft.com/en-us/library/system.activator.createinstance.aspx
ou (nouveau chemin)
https://docs.microsoft.com/en-us/dotnet/api/system.activator.createinstance
Voici quelques exemples simples :
ObjectType instance = (ObjectType)Activator.CreateInstance(objectType);
ObjectType instance = (ObjectType)Activator.CreateInstance("MyAssembly","MyNamespace.ObjectType");
Vous devez appeler 'Unwrap()' pour obtenir le type d'objet que vous souhaitez : ConcreteType instance = (ConcreteType)Activator.CreateInstance(objectType).Unwrap() ;
Comment ObjectType instance
correspond à la condition de l'OP "On ne peut pas toujours connaître le type d'un objet au moment de la compilation" ? :P
@Kevin Bien sûr. Une telle opération ne peut pas travailler dans un langage statiquement typé parce que cela n'a pas de sens. Vous ne pouvez pas invoquer des méthodes sur un objet de type inconnu. Entre-temps (= depuis que j'ai écrit cette réponse), C# a obtenu la fonction dynamic
construire qui fait permettent de telles constructions mais, dans la plupart des cas, cette réponse les couvre toujours.
@KonradRudolph Pas tout à fait vrai. D'abord du c# fait vous permettent de créer de nouveaux types au moment de l'exécution. Vous ne pouvez simplement rien appeler sur eux d'une manière statiquement sûre . Donc oui, vous avez à moitié raison. Mais de manière plus réaliste, vous en avez besoin lorsque vous chargez des assemblages au moment de l'exécution, ce qui signifie que le type n'est pas connu au moment de la compilation. C# serait sévèrement limité si vous ne pouviez pas faire cela. Vous venez d'ailleurs de le prouver vous-même : comment la méthode Activator qui prend une instance de type fonctionne-t-elle autrement ? Lorsque MS a écrit la classe Activator, ils n'avaient aucune connaissance à la compilation des futurs types que les utilisateurs écriraient.
@AnorZaken Mon commentaire ne dit rien sur la création de types au moment de l'exécution. Bien sûr, vous pouvez le faire, mais vous ne pouvez pas les utiliser statiquement dans le même contexte (vous pouvez héberger un programme complet compilé statiquement, bien sûr). C'est tout ce que mon commentaire dit.
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); } }
S'il s'agit d'un élément qui sera souvent appelé 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 l'option ConstructorInfo.Invoke()
. Deux options faciles pour la compilation dynamique sont compilées Expressions Linq ou un simple IL
opcodes et DynamicMethod
. Quoi qu'il en soit, la différence est énorme lorsque vous commencez à vous retrouver dans des boucles serrées ou des appels multiples.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.