如何从 C# ExpandoObject 按名称动态获取属性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19139417/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 14:13:22  来源:igfitidea点击:

How to dynamically get a property by name from a C# ExpandoObject?

c#asp.netoopdynamicreflection

提问by user2838966

I have an ExpandoObjectand want to make a getter for it that will return a property by name at runtime, where the name is specified in a string instead of hardcoded.

我有一个ExpandoObject并且想要为它制作一个 getter,它将在运行时按名称返回一个属性,其中名称在字符串中指定而不是硬编码。

For example, I CAN do this:

例如,我可以这样做:

account.features.isEmailEnabled;

and that will return true. accountis a ExpandoObject, and featuresis also an ExpandoObject. So I have an ExpandoObjectthat contains other ExpandoObjects.

这将返回true。 accountExpandoObjectfeatures也是ExpandoObject。所以我有一个ExpandoObject包含其他ExpandoObjects.

So what I want to be able to do is this:

所以我想要做的是:

account.features.GetProperty("isEmailEnabled");

and have that return true.

并让该返回为真。

The reason is that I have many features, and I want to be able to write one generic getter method where I can pass in the name of the feature I want, and the method will pass me back the value for account.features.whatever (where "whatever" is specified by passing in a string to the generic getter method). Otherwise I am going to have to write 30-some getters one for each feature.

原因是我有很多功能,我希望能够编写一个通用的getter方法,我可以在其中传入我想要的功能的名称,该方法会将 account.features.whatever 的值传回给我(其中“whatever”是通过将字符串传递给通用 getter 方法来指定的)。否则我将不得不为每个功能编写 30 个 getter。

I did a lot of research and tried doing something like:

我做了很多研究,并尝试做类似的事情:

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

followed by

其次是

var value = prop.GetProperty(featureNameAsString); 

but valuealways comes back as null. I don't understand why. In the watch window I can do account.features.isEmailEnabledand it shows true and says its a boolean. But if I try to get at this value using the approach above and pass in isEmailEnabledas the featureNameAsStringI just get null.

value总是返回空值。我不明白为什么。在监视窗口中,我可以做account.features.isEmailEnabled,它显示为 true 并表示它是一个布尔值。但是,如果我尝试使用上面的方法在这个值来获取和传递isEmailEnabled作为featureNameAsString我只是得到空。

Can someone please tell me what I may be doing wrong and what's a good approach, without it being too complex?

有人可以告诉我我可能做错了什么以及什么是好的方法,而不会太复杂?

I am working with ASP.NET under the 4.5.1 framework.

我在 4.5.1 框架下使用 ASP.NET。

采纳答案by Marc Gravell

ExpandoObjectprovides access both via dynamicand via IDictionary<string,object>- so you could just use the dictionary API:

ExpandoObject提供通过dynamic和通过访问IDictionary<string,object>- 所以你可以只使用字典 API:

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

Or if the name is fixed, just:

或者,如果名称是固定的,只需:

bool val = ((dynamic)account).features.isEmailEnabled;