web-dev-qa-db-ja.com

文字列を介してc#動的プロパティの値を取得する

文字列でdynamic c#プロパティの値にアクセスしたい:

dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };

文字列として「value2」しかない場合、どうすればd.value2(「ランダム」)の値を取得できますか? javascriptでは、d ["value2"]を実行して値(「ランダム」)にアクセスできますが、c#とリフレクションを使用してこれを行う方法はわかりません。一番近いのはこれです:

d.GetType().GetProperty("value2") ...しかし、それから実際の値を取得する方法がわかりません。

いつものように、あなたの助けに感謝します!

160
TimDog

PropertyInfoを(GetPropertyから)取得したら、GetValueを呼び出して、値を取得するインスタンスを渡す必要があります。あなたの場合:

d.GetType().GetProperty("value2").GetValue(d, null);
192
Adam Robinson
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);
}
36
IllidanS4

Dynamitey はオープンソースの.net stdライブラリであり、dynamicキーワードのように呼び出すことができますが、プロパティ名にコンパイラを使用するのではなく、文字列を使用して、最終的には- リフレクションの速度に等しい (これはdynamicキーワードを使用した場合ほど高速ではありませんが、これはコンパイラが静的にキャッシュする動的キャッシュの余分なオーバーヘッドによるものです).

Dynamic.InvokeGet(d,"value2");
22
jbtule

多くの場合、動的オブジェクトを要求すると、ExpandoObjectが取得されます(上記の質問の匿名で静的に型付けされた例ではありませんが、JavaScriptと、選択したJSONパーサーJsonFxは、ExpandoObjectsを生成します)。

ダイナミックが実際にExpandoObjectである場合、 http://msdn.Microsoft.com/en-gb/library/system.dynamicで説明されているように、IDictionaryにキャストすることでリフレクションを回避できます。 .expandoobject.aspx

IDictionaryにキャストすると、.Itemや.ContainsKeyなどの便利なメソッドにアクセスできます

7
Francis Norton

setterおよびgetterを含む任意のタイプで機能するプロパティのdynamicExpandoObjectの両方を取得する最も簡単な方法は、 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");
6
MaYaN

d.GetType()。GetProperty( "value2")

propertyInfoオブジェクトを返します。

それで

propertyInfo.GetValue(d)
4
James Gaunt

これは、動的のプロパティ値の値を取得した方法です。

    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)
        {

        }


    }
4

GetProperty/GetValueはJsonデータに対して機能せず、常にnull例外を生成しますが、このアプローチを試すことができます。

JsonConvertを使用してオブジェクトをシリアル化します。

var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));

次に、文字列に直接キャストしてアクセスします。

var pn = (string)z["DynamicFieldName"];

Convert.ToString(request)["DynamicFieldName"]をそのまま適用すると動作する場合がありますが、テストしていません。

3
Anderson

.GetType()nullを返したときにダイナミックドキュメントからプロパティを取得するには、これを試してください:

var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)doc);
var val = keyValuePairs["propertyName"].ToObject<YourModel>;
0
yzhai bruin