2010-09-07 12 views
1

Je voudrais implémenter une méthode qui me permet d'accéder à une propriété d'un objet inconnu/anonyme (-graph) de manière tardive/dynamique (je ne sais même pas comment l'appeler correctement).Comment accéder aux propriétés dynamiquement/en retard?

Voici un exemple de ce que je voudrais obtenir:

// setup an anonymous object 
var a = new { B = new { C = new { I = 33 } } }; 

// now get the value of a.B.C.I in a late-bound way 
var i = Get(a, "B.C.I"); 

Et voici une implémentation simple utilisant la réflexion « classique »:

public static object Get(object obj, string expression) 
{ 
    foreach (var name in expression.Split('.')) 
    { 
     var property = obj.GetType().GetProperty(name); 
     obj = property.GetValue(obj, null); 
    } 
    return obj; 
} 

Quelles autres options dois-je avec C#/.NET 4 pour mettre en œuvre quelque chose de similaire à celui montré ci-dessus, mais peut-être plus simple, plus performant, etc.?

Peut-être y a-t-il des façons de réaliser la même chose, ce qui me permettrait de spécifier expression en utilisant une expression lambda au lieu d'une chaîne? Les arbres d'expression seraient-ils utiles de quelque manière que ce soit (par exemple, comme indiqué dans this question)?

Mise à jour: l'objet et l'expression sont passés dans mon code via un appel de service Web. C'est pourquoi j'ai utilisé object et string dans ma méthode Get().

Répondre

2

Avez-vous effectivement seulement avoir l'expression comme une chaîne? Est-il connu au moment de la compilation, juste que les types eux-mêmes ne sont pas connus (ou sont difficiles à exprimer)? Si oui:

qui rend la vie beaucoup plus difficile, et aucun des 4 C# fonctionnalités vraiment vous aider
dynamic d = a; 
int i = d.B.C.I; 

Si vous vraiment avez seulement comme une chaîne (par exemple sous forme de données saisies par l'utilisateur). Vous pourriez potentiellement l'évaluer comme un script IronPython ou quelque chose comme ça ...

EDIT: D'accord, après la mise à jour, il semble que vous êtes dans la dernière situation - dans ce cas, je ne sais pas d'une plus belle manière que d'utiliser la réflexion. Certaines liaisons de propriétés intégrées créées pour les interfaces utilisateur peuvent aider, mais je ne connais pas de méthode d'accès propre.

+0

Désolé, je n'étais pas clair. J'ai mis à jour la question. – M4N

1

Si vous souhaitez utiliser le style C#, vous pouvez utiliser le compilateur Mono en tant que service à partir de votre application. Je décris comment faire ici: Mono Compiler as a Service (MCS)

Comme une approche alternative, vous pouvez utiliser la réflexion pour mettre toutes les propriétés de votre objet dans un ExpandoObject puis utilisez comme un dictionnaire (car ExpandoObject implémente IDictionary). Alternativement, vous pouvez utiliser JSON.NET et appeler JObject.FromObject, ce qui va transformer un objet régulier en un objet JObject qui est accessible dans un style de type dictionnaire (et un avantage supplémentaire a un support de graphe récursif). Enfin, vous pouvez utiliser la même approche pour vider votre objet dans un dictionnaire de dictionnaires.

Questions connexes