117 votes

Comment vérifier si un type fournit un constructeur sans paramètre?

Je voudrais vérifier si un type connu au moment de l'exécution fournit un constructeur sans paramètre. La classe Type n'a donné aucun résultat prometteur, alors je suppose que je dois utiliser la réflexion?

203voto

Alex J Points 4142

L' Type classe est la réflexion. Vous pouvez le faire:

Type theType = myobject.GetType(); // if you have an instance
// or
Type theType = typeof(MyObject); // if you know the type

var constructor = theType.GetConstructor(Type.EmptyTypes);

Elle renvoie null si un constructeur sans paramètre n'existe pas.


Si vous aussi vous voulez trouver les constructeurs privés, utilisez le légèrement plus long:

var constructor = theType.GetConstructor(
  BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, 
  null, Type.EmptyTypes, null);

Il y a une mise en garde pour les types de valeur, qui ne sont pas autorisés à avoir un constructeur par défaut. Vous pouvez vérifier si vous avez un type de la valeur à l'aide de l' Type.IsValueType de la propriété, et de créer des instances à l'aide d' Activator.CreateInstance(Type);

19voto

nawfal Points 13500
 type.GetConstructor(Type.EmptyTypes) != null
 

échouerait pour struct s. Mieux vaut l'étendre:

 public static bool HasDefaultConstructor(this Type t)
{
    return t.IsValueType || t.GetConstructor(Type.EmptyTypes) != null;
}
 

Succès puisque même enum s ont un constructeur par défaut sans paramètre. Également légèrement accéléré pour les types de valeur car l'appel de réflexion n'est pas effectué.

13voto

Henk Holterman Points 153608

Oui, vous devez utiliser la réflexion. Mais vous le faites déjà lorsque vous utilisez GetType()

Quelque chose comme:

 var t = x.GetType();
var c = t.GetConstructor(new Type[0]);
if (c != null) ...
 

9voto

BrokenGlass Points 91618

Cela devrait fonctionner:

    myClass.GetType().GetConstructors()
                    .All(c=>c.GetParameters().Length == 0)
 

4voto

KeithS Points 36130

Selon votre situation, vous pouvez également utiliser un générique de restriction de type:

public void DoSomethingWith<T>(T myObject) where T:new() {...}

La méthode ci-dessus déclaration de restreindre le type de paramètre à n'importe quel Objet qui peut être instancié avec un constructeur sans paramètre. L'avantage ici est que le compilateur va attraper toute tentative d'utilisation de la méthode avec une classe qui ne possède pas de constructeur sans paramètre, donc tant que le type est connu quelque part au moment de la compilation, cela va fonctionner et de vous avertir d'un problème plus tôt.

Bien sûr, si le type est vraiment connue qu'à l'exécution (c'est à dire que vous êtes à l'aide de l'Activateur.CreateInstance() pour instancier un objet basé sur une chaîne ou un Type construit) alors ce ne sera pas vous aider. J'utilise généralement la réflexion comme la dernière option, car une fois que vous êtes allé à la dynamique de la terre, vous devez rester dans la dynamique de la terre; il est généralement difficile, voire messier à instancier dynamiquement quelque chose et puis commencer à les traiter de manière statique.

Prograide.com

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.

Powered by:

X