Supposons que j'ai une variable dynamique:
dynamic d = *something*
Maintenant, quelque chose crée des propriétés à d
que j’ai en revanche à partir d’un tableau de chaînes:
string[] strarray = { 'property1','property2',..... }
Je ne connais pas les noms de propriété à l'avance.
Comment dans le code, une fois que d
est créé et que strarray est extrait de la base de données, puis-je obtenir les valeurs?
Je veux obtenir d.property1 , d.property2
.
Je vois que l'objet a un dictionnaire interne _dictionary
qui contient les clés et les valeurs, comment puis-je les récupérer?
Je ne sais pas s'il existe un moyen plus élégant avec des objets créés dynamiquement, mais utiliser un vieux reflet simple devrait fonctionner:
var nameOfProperty = "property1";
var propertyInfo = myObject.GetType().GetProperty(nameOfProperty);
var value = propertyInfo.GetValue(myObject, null);
GetProperty
retournera null
si le type de myObject
ne contient pas une propriété publique portant ce nom.
EDIT: Si l'objet n'est pas un objet "normal" mais quelque chose implémentant IDynamicMetaObjectProvider
, cette approche ne fonctionnera pas. S'il vous plaît jeter un oeil à cette question à la place:
Cela vous donnera tous les noms de propriété et les valeurs définies dans votre variable dynamique.
dynamic d = { // your code };
object o = d;
string[] propertyNames = o.GetType().GetProperties().Select(p => p.Name).ToArray();
foreach (var prop in propertyNames)
{
object propValue = o.GetType().GetProperty(prop).GetValue(o, null);
}
J'espère que cela vous aiderait:
public static object GetProperty(object o, string member)
{
if(o == null) throw new ArgumentNullException("o");
if(member == null) throw new ArgumentNullException("member");
Type scope = o.GetType();
IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider;
if(provider != null)
{
ParameterExpression param = Expression.Parameter(typeof(object));
DynamicMetaObject mobj = provider.GetMetaObject(param);
GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[]{CSharpArgumentInfo.Create(0, null)});
DynamicMetaObject ret = mobj.BindGetMember(binder);
BlockExpression final = Expression.Block(
Expression.Label(CallSiteBinder.UpdateLabel),
ret.Expression
);
LambdaExpression lambda = Expression.Lambda(final, param);
Delegate del = lambda.Compile();
return del.DynamicInvoke(o);
}else{
return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null);
}
}
string json = w.JSON;
var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });
DynamicJsonConverter.DynamicJsonObject obj =
(DynamicJsonConverter.DynamicJsonObject)serializer.Deserialize(json, typeof(object));
Maintenant obj._Dictionary
contient un dictionnaire. Parfait!
Ce code doit être utilisé conjointement avec Deserialize JSON en objet dynamique C #? + Rend la variable _dictionary de "private readonly" à public dans le code
Avez-vous vu la classe ExpandoObject?
Directement à partir de description MSDN : "Représente un objet dont les membres peuvent être ajoutés et supprimés dynamiquement au moment de l'exécution."
Avec cela, vous pouvez écrire du code comme ceci:
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
((IDictionary<String, Object>)employee).Remove("Name");
Si d a été créé par Newtonsoft, vous pouvez l’utiliser pour lire les noms et les valeurs des propriétés:
foreach (JProperty property in d)
{
DoSomething(property.Name, property.Value);
}
Utilisez le code suivant pour obtenir le nom et la valeur de la propriété d'un objet dynamique.
dynamic d = new { Property1= "Value1", Property2= "Value2"};
var properties = d.GetType().GetProperties();
foreach (var property in properties)
{
var PropertyName=property.Name;
//You get "Property1" as a result
var PropetyValue=d.GetType().GetProperty(property.Name).GetValue(d, null);
//You get "Value1" as a result
// you can use the PropertyName and Value here
}
Pouvez-vous essayer comme:
d?.property1 , d?.property2
J'ai testé et travaillé avec .netcore 2.1
Je pensais que cela pourrait aider quelqu'un à l'avenir.
Si vous connaissez déjà le nom de la propriété, vous pouvez procéder comme suit:
[HttpPost]
[Route("myRoute")]
public object SomeApiControllerMethod([FromBody] dynamic args){
var stringValue = args.MyPropertyName.ToString();
//do something with the string value. If this is an int, we can int.Parse it, or if it's a string, we can just use it directly.
//some more code here....
return stringValue;
}
vous pouvez utiliser "dynamicObject.PropertyName.Value
" pour obtenir directement la valeur de la propriété dynamique.
Exemple :
d.property11.Value