web-dev-qa-db-ja.com

C#ExpandoObjectから名前でプロパティを動的に取得する方法は?

ExpandoObjectがあり、実行時に名前でプロパティを返すゲッターを作成します。この場合、名前はハードコーディングされずに文字列で指定されます。

たとえば、私はこれを行うことができます:

account.features.isEmailEnabled;

そしてそれはtrueを返します。 accountExpandoObjectであり、featuresExpandoObjectです。したがって、他のExpandoObjectを含むExpandoObjectsがあります。

だから私ができることはこれです:

account.features.GetProperty("isEmailEnabled");

そしてそれがtrueを返すようにします。

その理由は、私には多くの機能があり、必要な機能の名前を渡すことができる一般的なゲッターメソッドを1つ作成できるようにしたいからです。このメソッドはaccount.features.whatever( 「何でも」は、文字列を汎用ゲッターメソッドに渡すことで指定されます)。それ以外の場合は、機能ごとに30個のゲッターを1つずつ作成する必要があります。

私は多くの研究を行い、次のようなことを試みました:

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

に続く

var value = prop.GetProperty(featureNameAsString); 

ただし、valueは常にnullとして返されます。理由がわかりません。ウォッチウィンドウでaccount.features.isEmailEnabledそしてそれは真を示し、ブール値を言います。しかし、上記のアプローチを使用してこの値を取得しようとして、isEmailEnabledfeatureNameAsStringとして渡すと、nullになります。

複雑すぎることなく、誰かが私が間違っていることと良いアプローチを教えてもらえますか?

4.5.1フレームワークでASP.NETを使用しています。

35
user2838966

ExpandoObjectdynamicIDictionary<string,object>の両方を介してアクセスを提供します-したがって、辞書APIを使用できます。

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

または、名前が固定されている場合、次のようにします。

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