Je voudrais accéder à la valeur d'une dynamic
propriété c # avec une chaîne:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
Comment puis-je obtenir la valeur de d.value2 ("random") si je n'ai que "value2" comme chaîne? En javascript, je pourrais faire d ["value2"] pour accéder à la valeur ("random"), mais je ne sais pas comment faire cela avec c # et la réflexion. Le plus proche que je suis venu est celui-ci:
d.GetType().GetProperty("value2")
... mais je ne sais pas comment en tirer la valeur réelle.
Comme toujours, merci pour votre aide!
Réponses:
Une fois que vous avez votre
PropertyInfo
(deGetProperty
), vous devez appelerGetValue
et transmettre l'instance dont vous souhaitez obtenir la valeur. Dans ton cas:la source
'd.GetType().GetProperty("value2").GetValue(d)' threw an exception of type 'System.Reflection.TargetInvocationException' dynamic {System.Reflection.TargetInvocationException}
dans la fenêtre de surveillance avec ça ..?new {}
crée un vrai type anonyme avec des propriétés définies, appeler GetType / GetProperty a du sens, mais qu'en est-il de ExpandoObject, qui si vous appelez GetType, vous obtiendrez un type qui a les propriétés de ExpandoObject, mais pas nécessairement ses propriétés dynamiques.Ajoutez une référence à Microsoft.CSharp. Fonctionne également pour les types dynamiques et les propriétés et champs privés.
Edit : Bien que cette approche fonctionne, il existe une méthode presque 20 fois plus rapide de l' assemblage Microsoft.VisualBasic.dll :
la source
d
dans la question).CallSite
code auCallByName
code, avez-vous comparé les deux lors de la mise en cache de l'CallSite
instance? Je soupçonne que le coût de votre première méthode est presque purement l'activation duBinder
etCallSite
, pas l'invocation deTarget()
Dynamitey est une
.net std
bibliothèque open source , qui vous permet de l'appeler comme ledynamic
mot - clé, mais en utilisant la chaîne a pour le nom de la propriété plutôt que le compilateur le faisant pour vous, et cela finit par être égal à la réflexion speedwise (ce qui n'est pas aussi rapide comme utilisant le mot-clé dynamic, mais cela est dû à la surcharge supplémentaire de la mise en cache dynamique, où le compilateur met en cache de manière statique).la source
La méthode la plus simple pour obtenir à la fois a
setter
et agetter
pour une propriété qui fonctionne pour tout type, y comprisdynamic
etExpandoObject
consiste à utiliserFastMember
ce qui se trouve être également la méthode la plus rapide (elle utilise Emit).Vous pouvez soit obtenir un
TypeAccessor
basé sur un type donné, soit unObjectAccessor
basé sur une instance d'un type donné.Exemple:
la source
La plupart du temps, lorsque vous demandez un objet dynamique, vous obtenez un ExpandoObject (pas dans l'exemple anonyme mais statique de la question ci-dessus, mais vous mentionnez JavaScript et mon analyseur JSON choisi JsonFx, pour sa part, génère ExpandoObjects).
Si votre dynamique est en fait un ExpandoObject, vous pouvez éviter la réflexion en le convertissant en IDictionary, comme décrit à http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx .
Une fois que vous avez converti en IDictionary, vous avez accès à des méthodes utiles telles que .Item et .ContainsKey
la source
Int64? i = data.value; //data is ExpandoObject
rechercherait et appellerait automatiquement l'opérateur implicite. D'un autre côté, si je devais utiliser IDictionary pour tester si le champ "valeur" existe, je récupérerais un objet qui ne sera pas converti sans erreur en Int64 ?.GetProperty / GetValue ne fonctionne pas pour les données Json, il génère toujours une exception null, cependant, vous pouvez essayer cette approche:
Sérialisez votre objet à l'aide de JsonConvert:
Ensuite, accédez-y directement en le renvoyant en chaîne:
Cela peut fonctionner directement en appliquant le Convert.ToString (request) ["DynamicFieldName"], mais je n'ai pas testé.
la source
new JavaScriptSerializer().Deserialize<object>(json);
pour accéder aux "propriétés" de la manière que vous avez suggéréerenvoie un objet PropertyInfo.
Alors fais
la source
GetValue(d)
besoins doivent êtreGetValue(d,null)
C'est ainsi que j'ai obtenu la valeur d'une valeur de propriété d'un dinamic:
la source
Pour obtenir les propriétés de la documentation dynamique lors des
.GetType()
retoursnull
, essayez ceci:la source
Dans .Net core 3.1, vous pouvez essayer comme ceci
la source
Similaire à la réponse acceptée, vous pouvez également essayer à la
GetField
place deGetProperty
.d.GetType().GetField("value2").GetValue(d);
Selon la façon dont le réel a
Type
été implémenté, cela peut fonctionner lorsque GetProperty () ne le fait pas et peut même être plus rapide.la source