J'ai un type (humain) et je veux savoir si je pouvais faire est-il possible de vérifier à l'avance Si J'ai essayé cela mais ça ne 'T Travailler: P> system.activator.createinstance (de l'homme) () code>. Donc, fondamentalement, je veux vérifier si l'homme a un constructeur de paramètres publics / ou un constructeur public avec des paramètres facultatifs permettant d'appeler
nouvel humain code> sans donner des arguments.
System.Activator.CreateInstance (de T) code> échouera? (Je veux dire autre que d'envelopper l'énoncé
System.ACtivator.CreateInstance (de l'homme) () code> dans une prise d'essai bien sûr ..) p>
Option Strict On : Option Explicit On
Module Test
Public Class Human
Public Sub New(Optional ByVal a As Integer = 1)
End Sub
End Class
Public Sub Main()
Dim c = GetType(Human).GetConstructor(System.Type.EmptyTypes)
MsgBox(c Is Nothing)
End Sub
End Module
4 Réponses :
Vous pouvez vérifier et vous assurer que votre type edit: p> Vous pouvez vérifier manuellement le constructeur sans paramètre comme celui-ci p > humain code> a un constructeur sans paramètre accessible. La meilleure façon de faire est de créer une méthode générique et d'ajouter une contrainte
où T: nouveau () code>
if(typeof(Human).GetType().GetConstructor(Type.EmptyTypes) !=null)
{
...
}
Je sais à propos de cette contrainte où T: Nouveau () Toutefois, j'ai besoin de t pour prendre en charge les deux types qui ont des contraintes nouveaux () code> et types qui n'ont pas cette contrainte
@Pacerier Les paramètres facultatifs le rend délicat. Mais @magnus Réponse a adressé cette zone.
Extra gettype () code> ne doit pas être utilisé comme type
typeof (humain) code> obtient déjà le type. (ou simplement utiliser
gettype () code> au lieu de
typeof () code>)
J'ai créé une application de console rapide à l'aide de la réflexion pour tester les constructeurs de paramètres sur des types. Est-ce ce dont vous avez besoin?
Pour vérifier si le constructeur est vide ou que tous les paramètres sont facultatifs:
var hasEmptyOrDefaultConstr = typeof(Human).GetConstructor(Type.EmptyTypes) != null || typeof(Human).GetConstructors(BindingFlags.Instance | BindingFlags.Public) .Any (x => x.GetParameters().All (p => p.IsOptional));
Cela ne fonctionne pas si j'ai un Sous-nouveau privé code> il me dit que c'est vrai. Mais si je fais `system.activator.createinstance (de l'homme) ()` Je vais avoir une exception bien sûr!
OK, j'ai mis à jour la réponse pour exclure des constructeurs non publics et statiques
ok cool j'ai installé avec ceci: dim is_activatable = gettype (humain) .betconstructeurs (système.reflection.bindingflag s.instance ou system.reflet.bindingflags.pindingflags.public). Nan (fonction (c) c.geparamètres .All (fonction (p) p.isoptional)) code>
BTW n'est-il pas bizarre qu'il n'y a pas de fonction intégrée isactivatable code>?
Je peux voir comment cela serait utile.
+1: merci. Comme la requête LINQ pour vérifier un constructeur avec tous les arguments facultatifs
Veuillez noter que Les paramètres facultatifs (ou arguments) sont résolus par le compilateur C # sur le site d'appel em>. Cependant, il n'y a pas de compilateur impliqué de manière à apposer le constructeur à l'aide de la réflexion. P> Si vous utilisez le code suivant, vous obtiendrez un En d'autres termes Les arguments facultatifs sont une chose compilatrice, pas une chose CLR. P> Pour plus d'informations sur "Cas d'angle avec facultatif Arguments "Voir cette récente série de blogs d'Eric Lippert: P> http://ericlippert.com/2011/05/09/Optional-argument-corner-cases-par-one/ P> Ayant cela dit, vous pourriez être Capable d'en quelque sorte répliquer le comportement souhaité en utilisant une réflexion plus poussée et créant manuellement les paramètres requis pour l'appel du constructeur. Le compilateur placera certains attributs à l'intérieur de l'assemblage que vous pourriez utiliser à cet effet, je suppose. P> Exemple: P> activator.createinstance
activator.createInstance (type) code> fonctionnera uniquement avec des constructeurs sans paramètre. Un constructeur avec uniquement des arguments facultatifs est pas em> paramètre sans paramètre dans ce sens.
mancheMethodException code> dire qu'il n'y a pas de Constructeur sans paramètre défini: p>
public class Foo
{
public Foo([Optional, DefaultParameterValue(5)] int optional)
{
Console.WriteLine("Constructed");
}
}
BTW Comment traduisons-nous votre dernier paragraphe en VB?
@Pacerier: Je ne suis pas tout à fait sûr de quoi vous parlez exactement, mais les attributs placés dans le code par le compilateur sont les mêmes pour C # et VB.NET, c'est-à-dire que les deux compilateurs semblent générer le même code à cet égard.
@ Christian.k je veux dire que je ne sais pas où mettre la ligne [facultatif, defaultParameValue (5)] b>. Cela ne compile pas pour moi: Sub NOUVEAU PUBLIC PUBLIC PUBLIC ([[[[Facultatif, DefaultParameValue (5)] BYVAL X en tant qu'integer) Classe de sous-fin entier)
@Pacerier Vous ne le mettez pas là-bas, cela fait votre compilateur (vb.net ou c #). Vous devez lire i> eux (en utilisant la réflexion). Pour rester dans l'esprit des autres réponses, vous pouvez faire quelque chose comme ceci: (1) Déterminez si vous avez un véritable constructeur sans paramètre, si oui, faites comme les autres suggérées. (2) Si vous avez un constructeur dans lequel tous les paramattres ont des valeurs par défaut (d'où les attributs indiqués dans "l'exemple" de ma réponse), vous utilisez la réflexion pour obtenir les valeurs et créer un objet approprié [] de le transmettre à l'activateur .CreateInstance-surcharge pour constructeurs sans paramètre.
Remarque, que cela ne fonctionnera pas / ne fonctionnera jamais de la case pour les constructeurs "avec seulement des arguments facultatifs". Voir ma réponse ci-dessous pour plus de détails et de fond.
Dupliqué possible de Comment puis-je vérifier si un type fournit un constructeur sans paramètre?