文字列でdynamic
c#プロパティの値にアクセスしたい:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
文字列として「value2」しかない場合、どうすればd.value2(「ランダム」)の値を取得できますか? javascriptでは、d ["value2"]を実行して値(「ランダム」)にアクセスできますが、c#とリフレクションを使用してこれを行う方法はわかりません。一番近いのはこれです:
d.GetType().GetProperty("value2")
...しかし、それから実際の値を取得する方法がわかりません。
いつものように、あなたの助けに感謝します!
PropertyInfo
を(GetProperty
から)取得したら、GetValue
を呼び出して、値を取得するインスタンスを渡す必要があります。あなたの場合:
d.GetType().GetProperty("value2").GetValue(d, null);
public static object GetProperty(object target, string name)
{
var site = System.Runtime.CompilerServices.CallSite<Func<System.Runtime.CompilerServices.CallSite, object, object>>.Create(Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, name, target.GetType(), new[]{Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(0,null)}));
return site.Target(site, target);
}
Microsoft.CSharpへの参照を追加します。動的な型、プライベートプロパティ、およびフィールドでも機能します。
編集:このアプローチは機能しますが、Microsoft.VisualBasic.dllアセンブリからほぼ20倍高速なメソッドがあります。
public static object GetProperty(object target, string name)
{
return Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(target, name, CallType.Get);
}
Dynamitey はオープンソースの.net std
ライブラリであり、dynamic
キーワードのように呼び出すことができますが、プロパティ名にコンパイラを使用するのではなく、文字列を使用して、最終的には- リフレクションの速度に等しい (これはdynamicキーワードを使用した場合ほど高速ではありませんが、これはコンパイラが静的にキャッシュする動的キャッシュの余分なオーバーヘッドによるものです).
Dynamic.InvokeGet(d,"value2");
多くの場合、動的オブジェクトを要求すると、ExpandoObjectが取得されます(上記の質問の匿名で静的に型付けされた例ではありませんが、JavaScriptと、選択したJSONパーサーJsonFxは、ExpandoObjectsを生成します)。
ダイナミックが実際にExpandoObjectである場合、 http://msdn.Microsoft.com/en-gb/library/system.dynamicで説明されているように、IDictionaryにキャストすることでリフレクションを回避できます。 .expandoobject.aspx 。
IDictionaryにキャストすると、.Itemや.ContainsKeyなどの便利なメソッドにアクセスできます
setter
およびgetter
を含む任意のタイプで機能するプロパティのdynamic
とExpandoObject
の両方を取得する最も簡単な方法は、 FastMember
を使用することです(これは、Emitを使用して最も高速な方法でもあります)。
特定の型に基づいてTypeAccessor
を取得するか、特定の型のインスタンスに基づいてObjectAccessor
を取得できます。
例:
var staticData = new Test { Id = 1, Name = "France" };
var objAccessor = ObjectAccessor.Create(staticData);
objAccessor["Id"].Should().Be(1);
objAccessor["Name"].Should().Be("France");
var anonymous = new { Id = 2, Name = "Hilton" };
objAccessor = ObjectAccessor.Create(anonymous);
objAccessor["Id"].Should().Be(2);
objAccessor["Name"].Should().Be("Hilton");
dynamic expando = new ExpandoObject();
expando.Id = 3;
expando.Name = "Monica";
objAccessor = ObjectAccessor.Create(expando);
objAccessor["Id"].Should().Be(3);
objAccessor["Name"].Should().Be("Monica");
var typeAccessor = TypeAccessor.Create(staticData.GetType());
typeAccessor[staticData, "Id"].Should().Be(1);
typeAccessor[staticData, "Name"].Should().Be("France");
typeAccessor = TypeAccessor.Create(anonymous.GetType());
typeAccessor[anonymous, "Id"].Should().Be(2);
typeAccessor[anonymous, "Name"].Should().Be("Hilton");
typeAccessor = TypeAccessor.Create(expando.GetType());
((int)typeAccessor[expando, "Id"]).Should().Be(3);
((string)typeAccessor[expando, "Name"]).Should().Be("Monica");
d.GetType()。GetProperty( "value2")
propertyInfoオブジェクトを返します。
それで
propertyInfo.GetValue(d)
これは、動的のプロパティ値の値を取得した方法です。
public dynamic Post(dynamic value)
{
try
{
if (value != null)
{
var valorCampos = "";
foreach (Newtonsoft.Json.Linq.JProperty item in value)
{
if (item.Name == "valorCampo")//property name
valorCampos = item.Value.ToString();
}
}
}
catch (Exception ex)
{
}
}
GetProperty/GetValueはJsonデータに対して機能せず、常にnull例外を生成しますが、このアプローチを試すことができます。
JsonConvertを使用してオブジェクトをシリアル化します。
var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));
次に、文字列に直接キャストしてアクセスします。
var pn = (string)z["DynamicFieldName"];
Convert.ToString(request)["DynamicFieldName"]をそのまま適用すると動作する場合がありますが、テストしていません。
.GetType()
がnull
を返したときにダイナミックドキュメントからプロパティを取得するには、これを試してください:
var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)doc);
var val = keyValuePairs["propertyName"].ToObject<YourModel>;