Comment détecter si une propriété existe sur un ExpandoObject?
En javascript, vous pouvez détecter si une propriété est définie à l'aide de la non défini mot-clé:
if( typeof data.myProperty == "undefined" ) ...
Comment voulez-vous faire cela en C# en utilisant le mot-clé dynamic avec un ExpandoObject
et sans jeter une exception?
- Notez que le code ne vérifie pas la valeur de
data.myProperty
; il vérifie quetypeof data.myProperty
retourne. Il est exact quedata.myProperty
peuvent exister et être mis àundefined
, mais dans ce cas,typeof
sera de retour quelque chose d'autre que"undefined"
. Si ce code ne fonctionne pas.
InformationsquelleAutor Softlion | 2010-05-15
Vous devez vous connecter pour publier un commentaire.
Selon MSDN la déclaration montre que c'est la mise en œuvre de IDictionary:
Vous pouvez l'utiliser pour voir si un membre est défini:
IDictionary<String, object>
vraiment nécessaire? Si elle implémente cette interface, ne devrait-on pas appelerContainsKey()
simplement de travailler?Une distinction importante doit être faite ici.
La plupart des réponses ici sont spécifiques à la ExpandoObject qui est mentionné dans la question. Mais une utilisation courante (et la raison pour atterrir sur cette question lors de la recherche), c'est quand à l'aide de la ASP.Net MVC ViewBag. C'est une coutume de mise en œuvre/sous-classe de DynamicObject, ce qui ne va pas faire une Exception lorsque vous vérifiez tout arbitraire nom de la propriété pour les nuls. Supposons que vous pouvez déclarer une propriété comme:
Ensuite, supposons que vous vouliez vérifier sa valeur, et si c'est même set - si elle existe. Ce qui suit est valable, de compiler, de ne pas jeter des exceptions, et vous donne la bonne réponse:
Maintenant, se débarrasser de la déclaration de EnableThinger. Même code compile et s'exécute correctement. Nul besoin de réflexion.
Contrairement à ViewBag, ExpandoObject va jeter si vous rechercher la valeur null sur une propriété qui n'existe pas. Afin d'obtenir MVC ViewBag est plus doux de la fonctionnalité de votre
dynamic
objets, vous aurez besoin d'utiliser une mise en œuvre de dynamiques qui ne jette pas.Vous pouvez simplement utiliser l'exacte mise en œuvre dans MVC ViewBag:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/DynamicViewDataDictionary.cs
Vous pouvez voir qu'il est lié dans MVC Vues ici, dans MVC ViewPage:
http://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/ViewPage.cs
La clé de DynamicViewDataDictionary gracieuse de comportement est le Dictionnaire de la mise en œuvre sur ViewDataDictionary, ici:
https://github.com/ASP-NET-MVC/aspnetwebstack/blob/master/src/System.Web.Mvc/ViewDataDictionary.cs
En d'autres termes, il renvoie toujours une valeur pour toutes les touches, indépendamment de ce qu'il contient - il simplement renvoie la valeur null lorsque rien n'est là. Mais, ViewDataDictionary a le fardeau d'être lié à la MVC du Modèle, il est donc préférable de bande, la gracieuse dictionnaire pièces pour utilisation à l'extérieur MVC Vues.
C'est trop long à vraiment écrire toutes les tripes ici - plus de la mise en œuvre de IDictionary - mais ici, c'est un objet dynamique qui ne renvoie pas null contrôles sur les propriétés qui n'ont pas été déclarées, sur Github:
https://github.com/b9chris/GracefulDynamicDictionary
Si vous voulez juste pour l'ajouter à votre projet via NuGet, son nom est GracefulDynamicDictionary.
J'ai répondu à une question très semblable récemment: Comment dois-je réfléchir sur les membres de la dynamique de l'objet?
Peu de temps, ExpandoObject n'est pas la seule dynamique de l'objet que vous pourriez obtenir. La réflexion pourrait fonctionner pour les types statiques (les types qui ne mettent pas en œuvre idynamicmetaobjectprovider fournie par). Pour les types qui implémentent cette interface, la réflexion est pratiquement inutile. Pour ExpandoObject, vous pouvez simplement vérifier si la propriété est définie comme une clé dans le dictionnaire sous-jacent. Pour les autres implémentations, il peut être difficile et, parfois, la seule façon est de travailler avec des exceptions. Pour plus de détails, suivez le lien ci-dessus.
Mise à JOUR: Vous pouvez utiliser les délégués et essayer d'obtenir une valeur de la dynamique de la propriété de l'objet, si elle existe. Si il n'y a pas de propriété, il suffit d'intercepter l'exception et retourne la valeur false.
Prendre un coup d'oeil, il fonctionne très bien pour moi:
La sortie du code est le suivant:
IsPropertyExist
. Dans cet exemple, vous savez, on peut jeter unInvalidOperationException
. Dans la pratique, vous n'avez aucune idée de ce que l'exception peut être levée. +1 pour contrer le culte du cargo.J'ai voulu créer un méthode d'extension si je pouvais faire quelque chose comme:
... mais vous ne pouvez pas créer des extensions sur
ExpandoObject
selon le C# 5 de la documentation (plus d'info ici).J'ai donc fini par la création d'une classe helper:
Pour l'utiliser:
Pourquoi vous ne voulez pas utiliser la Réflexion pour obtenir jeu de type properyes? Comme ce
Cette méthode d'extension vérifie l'existence d'une propriété, puis renvoie la valeur ou la valeur null. Ceci est utile si vous ne voulez pas que vos applications de jeter inutilement des exceptions, au moins ceux que vous pouvez aider.
Si peut être utilisé en tant que tel :
ou si votre variable locale est "dynamique", vous aurez à le jeter aux ExpandoObject premier.
Hé les gars cesser d'utiliser la Réflexion pour tout, il en coûte beaucoup de cycles de PROCESSEUR.
Voici la solution:
Essayer celui-ci
dynamic
objets (renvoie toujoursnull
).