J'aimerais accéder à la valeur d'une propriété dynamic
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 "valeur2" en tant que 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 la suivante:
d.GetType().GetProperty("value2")
... mais je ne sais pas comment en tirer la valeur réelle.
Comme toujours, merci pour votre aide!
Une fois que vous avez votre PropertyInfo
(de GetProperty
), vous devez appeler GetValue
et transmettre l'instance dont vous voulez obtenir la valeur. Dans ton cas:
d.GetType().GetProperty("value2").GetValue(d, null);
public static object GetProperty(object target, string name)
{
var site = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, name, target.GetType(), new[]{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0,null)}));
return site.Target(site, target);
}
Ajouter 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 près de 20 × méthodes plus rapides de l'assembly Microsoft.VisualBasic.dll :
public static object GetProperty(object target, string name)
{
return Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(target, name, CallType.Get);
}
Dynamitey est une bibliothèque open source .net std
, que vous pouvez appeler comme le mot clé dynamic
, mais en utilisant une chaîne pour le nom de la propriété plutôt que le compilateur le faisant à votre place. , et cela finit par être égal à la réflexion speedwise (ce qui n’est pas aussi rapide que d’utiliser le mot-clé dynamic, mais cela est dû à la surcharge de la mise en cache dynamique, où le compilateur met en cache de manière statique).
Dynamic.InvokeGet(d,"value2");
La méthode la plus simple pour obtenir un setter
et un getter
pour une propriété qui fonctionne pour tout type, y compris dynamic
et ExpandoObject
consiste à utiliser FastMember
qui se trouve être la méthode la plus rapide autour de (utilise Emit).
Vous pouvez obtenir un TypeAccessor
basé sur un type donné ou un ObjectAccessor
basé sur une instance d'un type donné.
Exemple:
var staticData = new Test { Id = 1, Name = "France" };
var objAccessor = ObjectAccessor.Create(staticData);
objAccessor["Id"].Should().Be(1);
objAccessor["Name"].Should().Be("France");
var anonymous = new { Id = 2, Name = "Hilton" };
objAccessor = ObjectAccessor.Create(anonymous);
objAccessor["Id"].Should().Be(2);
objAccessor["Name"].Should().Be("Hilton");
dynamic expando = new ExpandoObject();
expando.Id = 3;
expando.Name = "Monica";
objAccessor = ObjectAccessor.Create(expando);
objAccessor["Id"].Should().Be(3);
objAccessor["Name"].Should().Be("Monica");
var typeAccessor = TypeAccessor.Create(staticData.GetType());
typeAccessor[staticData, "Id"].Should().Be(1);
typeAccessor[staticData, "Name"].Should().Be("France");
typeAccessor = TypeAccessor.Create(anonymous.GetType());
typeAccessor[anonymous, "Id"].Should().Be(2);
typeAccessor[anonymous, "Name"].Should().Be("Hilton");
typeAccessor = TypeAccessor.Create(expando.GetType());
((int)typeAccessor[expando, "Id"]).Should().Be(3);
((string)typeAccessor[expando, "Name"]).Should().Be("Monica");
La plupart du temps, lorsque vous demandez un objet dynamique, vous obtenez un ExpandoObject (pas dans l'exemple ci-dessus de type anonyme mais statiquement, mais vous mentionnez JavaScript et l'analyseur JSON choisi, JsonFx, génère ExpandoObjects).
Si votre dynamique est en fait un ExpandoObject, vous pouvez éviter les réflexions en le transmettant à IDictionary, comme décrit à l'adresse http://msdn.Microsoft.com/en-gb/library/system.dynamic .expandoobject.aspx .
Une fois que vous avez converti à IDictionary, vous avez accès à des méthodes utiles telles que .Item et .ContainsKey.
d.GetType (). GetProperty ("valeur2")
renvoie un objet PropertyInfo.
Alors alors fais
propertyInfo.GetValue(d)
GetProperty/GetValue ne fonctionne pas pour les données Json, il génère toujours une exception null. Toutefois, vous pouvez essayer cette approche:
Sérialisez votre objet en utilisant JsonConvert:
var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));
Puis accédez-y directement en le renvoyant à la chaîne:
var pn = (string)z["DynamicFieldName"];
Cela peut fonctionner directement en appliquant Convert.ToString (request) ["DynamicFieldName"], mais je n'ai pas encore testé.
C’est ainsi que j’ai obtenu la valeur d’une propriété, propriété d’une dinamique:
public dynamic Post(dynamic value)
{
try
{
if (value != null)
{
var valorCampos = "";
foreach (Newtonsoft.Json.Linq.JProperty item in value)
{
if (item.Name == "valorCampo")//property name
valorCampos = item.Value.ToString();
}
}
}
catch (Exception ex)
{
}
}
Pour obtenir les propriétés d'un document dynamique lorsque .GetType()
renvoie null
, essayez ceci:
var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)doc);
var val = keyValuePairs["propertyName"].ToObject<YourModel>;