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

问题描述 投票:0回答:2

我有一个

ExpandoObject
并想为其创建一个 getter,它将在运行时按名称返回一个属性,其中名称是在字符串中指定的,而不是硬编码的。

例如,我可以这样做:

account.features.isEmailEnabled;

这将返回 true。

account
ExpandoObject
features
也是
ExpandoObject
。所以我有一个
ExpandoObject
,其中包含其他
ExpandoObjects

所以我想要做的是:

account.features.GetProperty("isEmailEnabled");

并让其返回 true。

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

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

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

随后

var value = prop.GetProperty(featureNameAsString); 

但是

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

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

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

c# asp.net oop dynamic reflection
2个回答
110
投票

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

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

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

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

0
投票

您可以使用扩展方法来完成您需要的操作:

public static T Get<T>(this ExpandoObject expO, string prop)
{
    return (T)((IDictionary<string, object>)expO)[prop];
}

使用示例:

account.features.Get<bool>("isEmailEnabled");
© www.soinside.com 2019 - 2024. All rights reserved.