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?
Réponses
Trop de publicités?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)
;
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é.
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.