Question

Je voudrais mettre en œuvre une méthode qui me permet d'accéder à une propriété d'un inconnu / objet anonyme (-graph) d'une manière tardive liée / dynamique (je ne sais même pas comment appeler correctement il).

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, comme indiqué ci-dessus, mais peut-être plus simple, plus performant, etc.?

Peut-être qu'il ya des façons de réaliser la même chose, ce qui me permettrait de préciser expression en utilisant une expression lambda au lieu d'une chaîne? Would expression de quelque manière que ce soit utile des arbres (par exemple, comme le montre cette question ) ?

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

Était-ce utile?

La solution

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

dynamic d = a;
int i = d.B.C.I;

Si vous vraiment ne l'avoir comme une chaîne (par exemple sous forme de données saisies par l'utilisateur) qui rend la vie beaucoup plus difficile, et aucun des C # 4 caractéristiques vraiment vous aider. Vous pourriez éventuellement évaluer comme un script IronPython ou quelque chose comme ça ...

EDIT: D'accord, après la mise à jour il semble que vous êtes dans cette dernière situation - dans ce cas, je ne sais pas d'une manière plus agréable que d'utiliser la réflexion. Une partie de la propriété intégrée liaison construite pour UIs peut aider, mais je ne sais pas d'une manière propre d'y accéder.

Autres conseils

Si vous voulez utiliser le style C #, vous pouvez utiliser le compilateur Mono en tant que service de votre application. Je décris comment faire ici: compilateur Mono en tant que service (MCS)

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 met en œuvre IDictionary). Sinon, vous pouvez utiliser JSON.NET et appel JObject.FromObject, qui transformera un objet ordinaire en jobject qui est accessible dans un dictionnaire comme le style (et comme un avantage supplémentaire a un support graphique récursive). Enfin, vous pouvez utiliser la même approche pour vider votre objet dans un dictionnaire de dictionnaires.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top