Moyen le plus efficace pour obtenir le constructeur par défaut d’un type

Quel est le moyen le plus efficace pour obtenir le constructeur par défaut (constructeur d’instance sans parameters) d’un System.Type?

Je pensais à quelque chose comme le code ci-dessous, mais il semble qu’il devrait y avoir un moyen plus simple et plus efficace de le faire.

Type type = typeof(FooBar) BindingFlags flags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance; type.GetConstructors(flags) .Where(constructor => constructor.GetParameters().Length == 0) .First(); 

 type.GetConstructor(Type.EmptyTypes) 

Si vous avez réellement besoin de l’object ConstructorInfo, consultez la réponse de Curt Hagenlocher .

D’un autre côté, si vous essayez simplement de créer un object au moment de l’exécution à partir d’un System.Type , consultez System.Activator.CreateInstance – il ne s’agit pas seulement de faire face à l’avenir (Activator gère plus de détails que ConstructorInfo.Invoke ). , c’est aussi beaucoup moins laid.

Si vous avez le paramètre de type générique, alors la réponse de Jeff Bridgman est la meilleure. Si vous avez seulement un object Type représentant le type que vous voulez construire, vous pouvez utiliser Activator.CreateInstance(Type) comme suggéré par Alex Lyman, mais on m’a dit que c’était lent (je ne l’ai pas personnellement profilé).

Cependant, si vous vous retrouvez à construire ces objects très fréquemment, il existe une approche plus eloquent utilisant des expressions Linq compilées dynamicment:

 using System; using System.Linq.Expressions; public static class TypeHelper { public static Func CreateDefaultConstructor(Type type) { NewExpression newExp = Expression.New(type); // Create a new lambda expression with the NewExpression as the body. var lambda = Expression.Lambda>(newExp); // Comstack our new lambda expression. return lambda.Comstack(); } } 

Appelez simplement le délégué qui vous est retourné. Vous devez mettre ce délégué en cache, car la recompilation constante des expressions Linq peut être coûteuse, mais si vous mettez le délégué en cache et le réutilisez à chaque fois, cela peut être très rapide! J’utilise personnellement un dictionnaire de recherche statique indexé par type. Cette fonction est pratique lorsque vous traitez avec des objects sérialisés où vous ne pouvez connaître que les informations de type.

REMARQUE: Cela peut échouer si le type n’est pas constructible ou s’il n’a pas de constructeur par défaut!

Si vous souhaitez uniquement obtenir le constructeur par défaut pour instancier la classe et obtenir le type en tant que paramètre de type générique pour une fonction, vous pouvez effectuer les opérations suivantes:

 T NewItUp() where T : new() { return new T(); } 

vous souhaitez essayer FormatterServices.GetUninitializedObject (Type), celui-ci est meilleur que Activator.CreateInstance

Cependant, cette méthode n’appelle pas le constructeur d’object, donc si vous définissez les valeurs initiales, cela ne fonctionnera pas. Vérifiez MSDN pour cette chose .serialization.formatterservices.getuninitializedobject.aspx

il y a une autre manière ici http://www.ozcandegirmenci.com/post/2008/02/Create-object-instances-Faster-than-Reflection.aspx

cependant celui-ci échoue si l’object a des constructeurs paramétrés

J’espère que cela t’aides