web-dev-qa-db-fra.com

Comment obtenir dynamiquement une propriété par son nom à partir d'un ExpandoObject C #?

J'ai un ExpandoObject et je veux en faire un getter qui retournera une propriété par son nom au moment de l'exécution, où le nom est spécifié dans une chaîne au lieu d'être codé en dur.

Par exemple, je peux le faire:

account.features.isEmailEnabled;

et cela reviendra vrai. account est un ExpandoObject et features est également un ExpandoObject. J'ai donc un ExpandoObject qui contient d'autres ExpandoObjects.

Donc, ce que je veux pouvoir faire, c'est ceci:

account.features.GetProperty("isEmailEnabled");

et que ce retour soit vrai.

La raison en est que j'ai de nombreuses fonctionnalités, et je veux pouvoir écrire une méthode getter générique où je peux transmettre le nom de la fonctionnalité que je veux, et la méthode me transmettra la valeur de account.features.wimporte ( où "quoi que ce soit" est spécifié en passant une chaîne à la méthode getter générique). Sinon, je vais devoir écrire une trentaine de getters pour chaque fonctionnalité.

J'ai fait beaucoup de recherches et essayé de faire quelque chose comme:

var prop = account.features.GetType();  
// this returns System.Dyanmic.ExpandoObject

suivi par

var value = prop.GetProperty(featureNameAsString); 

mais value revient toujours comme nul. Je ne comprends pas pourquoi. Dans la fenêtre de surveillance, je peux faire account.features.isEmailEnabled et cela montre vrai et dit que c'est un booléen. Mais si j'essaye d'obtenir cette valeur en utilisant l'approche ci-dessus et que je passe isEmailEnabled comme featureNameAsString je reçois juste null.

Quelqu'un peut-il me dire ce que je fais mal et quelle est la bonne approche, sans que cela soit trop complexe?

Je travaille avec ASP.NET sous le framework 4.5.1.

35
user2838966

ExpandoObject permet d'accéder à la fois via dynamic et via IDictionary<string,object> - vous pouvez donc simplement utiliser l'API dictionnaire:

var byName = (IDictionary<string,object>)account.features;
bool val = (bool)byName["isEmailEnabled"];

Ou si le nom est fixe, juste:

bool val = ((dynamic)account).features.isEmailEnabled;
66
Marc Gravell