.NET 4のdynamicキーワードで宣言されたオブジェクトからプロパティとその値の辞書を取得する必要がありますか?これにリフレクションを使用すると機能しないようです。
例:
dynamic s = new ExpandoObject();
s.Path = "/Home";
s.Name = "Home";
// How do I enumerate the Path and Name properties and get their values?
IDictionary<string, object> propertyValues = ???
IDynamicMetaObjectProviderが動的メンバー名を提供できる場合、それらを取得できます。 GetMemberNames ApacheライセンスPCLライブラリでの実装を参照してください Dynamitey (nugetにあります)、ExpandoObject
sおよびDynamicObject
sに対して実装されますGetDynamicMemberNames
およびその他のIDynamicMetaObjectProvider
は、is IDynamicMetaObjectProvider
を超えるカスタムテストなしでGetDynamicMemberNames
の実装をメタオブジェクトに提供します。
メンバー名を取得した後、値を正しい方法で取得するのは少し手間がかかりますが、Impromptuはこれを行いますが、興味深い部分だけを指し示して意味を持たせることは困難です。 ドキュメント であり、リフレクションと同等またはそれより高速ですが、expandoの辞書検索よりも高速ではない可能性がありますが、expando、dynamicまたはoriginalのオブジェクトに対して機能します-名前を付けます。
ExpandoObjectの場合、ExpandoObjectクラスは実際にそのプロパティにIDictionary<string, object>
を実装するため、ソリューションはキャストと同じくらい簡単です。
IDictionary<string, object> propertyValues = (IDictionary<string, object>)s;
これは一般的な動的オブジェクトでは機能しないことに注意してください。これらの場合、IDynamicMetaObjectProviderを介してDLRにドロップダウンする必要があります。
考慮すべきいくつかのシナリオがあります。まず、オブジェクトのタイプを確認する必要があります。このために、単にGetType()を呼び出すことができます。タイプがIDynamicMetaObjectProviderを実装していない場合、他のオブジェクトと同じリフレクションを使用できます。何かのようなもの:
var propertyInfo = test.GetType().GetProperties();
ただし、IDynamicMetaObjectProvider実装の場合、単純なリフレクションは機能しません。基本的に、このオブジェクトについてもっと知る必要があります。 ExpandoObject(IDynamicMetaObjectProvider実装の1つ)である場合、itowlsonが提供する回答を使用できます。 ExpandoObjectはそのプロパティをディクショナリに保存し、動的オブジェクトをディクショナリにキャストするだけです。
DynamicObject(別のIDynamicMetaObjectProvider実装)の場合、このDynamicObjectが公開するメソッドを使用する必要があります。 DynamicObjectは、プロパティのリストをどこにでも実際に「保存」する必要はありません。たとえば、次のようになります( my blog post の例を再利用しています):
public class SampleObject : DynamicObject
{
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = binder.Name;
return true;
}
}
この場合、(任意の名前で)プロパティにアクセスしようとすると、オブジェクトは単にプロパティの名前を文字列として返します。
dynamic obj = new SampleObject();
Console.WriteLine(obj.SampleProperty);
//Prints "SampleProperty".
したがって、何も反映する必要はありません。このオブジェクトにはプロパティがなく、同時にすべての有効なプロパティ名が機能します。
IDynamicMetaObjectProvider実装の場合、ExpandoObjectなどのプロパティのリストを取得し、残りは無視(または例外をスロー)できる既知の実装でフィルタリングする必要があります。
Newtonsoft Json.Netが必要
少し遅れましたが、私はこれを思いつきました。それはあなただけのキーを提供し、それからあなたはダイナミックでそれらを使用することができます:
public List<string> GetPropertyKeysForDynamic(dynamic dynamicToGetPropertiesFor)
{
JObject attributesAsJObject = dynamicToGetPropertiesFor;
Dictionary<string, object> values = attributesAsJObject.ToObject<Dictionary<string, object>>();
List<string> toReturn = new List<string>();
foreach (string key in values.Keys)
{
toReturn.Add(key);
}
return toReturn;
}
次に、このように単にforeachします:
foreach(string propertyName in GetPropertyKeysForDynamic(dynamicToGetPropertiesFor))
{
dynamic/object/string propertyValue = dynamicToGetPropertiesFor[propertyName];
// And
dynamicToGetPropertiesFor[propertyName] = "Your Value"; // Or an object value
}
値を文字列または他のオブジェクトとして取得するか、別の動的な操作を実行してルックアップを再度使用することを選択します。