web-dev-qa-db-ja.com

文字列でC#動的オブジェクトからプロパティ値を取得(リフレクション?)

動的変数があると仮定します。

dynamic d = *something*

さて、somethingdに対するプロパティを作成しますが、これは文字列配列から持っています:

string[] strarray = { 'property1','property2',..... }

事前にプロパティ名がわかりません。

dが作成され、strarrayがDBから取得されると、コードでどのように値を取得できますか?

d.property1 , d.property2を取得したい。

オブジェクトには、キーと値を含む_dictionary内部辞書がありますが、それらを取得するにはどうすればよいですか?

66
sergata.NET LTD

動的に作成されたオブジェクトにもっとエレガントな方法があるかどうかはわかりませんが、単純な古いリフレクションを使用すると動作するはずです:

var nameOfProperty = "property1";
var propertyInfo = myObject.GetType().GetProperty(nameOfProperty);
var value = propertyInfo.GetValue(myObject, null);

GetPropertyのタイプにこの名前のパブリックプロパティが含まれていない場合、nullmyObjectを返します。


EDIT:オブジェクトが「通常の」オブジェクトではなく、IDynamicMetaObjectProviderを実装するものである場合、このアプローチは機能しません。代わりにこの質問をご覧ください。

93
Heinzi

これにより、ダイナミック変数で定義されたすべてのプロパティ名と値が得られます。

dynamic d = { // your code };
object o = d;
string[] propertyNames = o.GetType().GetProperties().Select(p => p.Name).ToArray();
foreach (var prop in propertyNames)
{
    object propValue = o.GetType().GetProperty(prop).GetValue(o, null);
}
25

これがあなたを助けることを願っています:

public static object GetProperty(object o, string member)
{
    if(o == null) throw new ArgumentNullException("o");
    if(member == null) throw new ArgumentNullException("member");
    Type scope = o.GetType();
    IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider;
    if(provider != null)
    {
        ParameterExpression param = Expression.Parameter(typeof(object));
        DynamicMetaObject mobj = provider.GetMetaObject(param);
        GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[]{CSharpArgumentInfo.Create(0, null)});
        DynamicMetaObject ret = mobj.BindGetMember(binder);
        BlockExpression final = Expression.Block(
            Expression.Label(CallSiteBinder.UpdateLabel),
            ret.Expression
        );
        LambdaExpression lambda = Expression.Lambda(final, param);
        Delegate del = lambda.Compile();
        return del.DynamicInvoke(o);
    }else{
        return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null);
    }
}
20
IllidanS4
string json = w.JSON;

var serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });

DynamicJsonConverter.DynamicJsonObject obj = 
      (DynamicJsonConverter.DynamicJsonObject)serializer.Deserialize(json, typeof(object));

obj._Dictionaryには辞書が含まれるようになりました。パーフェクト!

このコードは JSONをC#動的オブジェクトにデシリアライズしますか? +で使用する必要があります。

5
sergata.NET LTD

ExpandoObjectクラスを見ましたか?

MSDNの説明 から直接:「実行時に動的にメンバーを追加および削除できるオブジェクトを表します。」

これを使用すると、次のようなコードを記述できます。

dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
((IDictionary<String, Object>)employee).Remove("Name");
4
ADIMO

DがNewtonsoftによって作成された場合、これを使用してプロパティ名と値を読み取ることができます。

    foreach (JProperty property in d)
    {
        DoSomething(property.Name, property.Value);
    }
3
user3285954

dynamicObject.PropertyName.Value」を使用して、動的プロパティの値を直接取得できます。

d.property11.Value
1
abhishek shetye

次のコードを使用して、動的オブジェクトのプロパティの名前と値を取得します。

dynamic d = new { Property1= "Value1", Property2= "Value2"};

var properties = d.GetType().GetProperties();
foreach (var property in properties)
{
    var PropertyName=property.Name; 
//You get "Property1" as a result

  var PropetyValue=d.GetType().GetProperty(property.Name).GetValue(d, null); 
//You get "Value1" as a result

// you can use the PropertyName and Value here
 }
1
Ghebrehiywet

のように試すことができます:

d?.property1 , d?.property2

.netcore 2.1をテストして使用した

0
Deepak Shaw

これは将来誰かを助けるかもしれないと思った。

プロパティ名がすでにわかっている場合は、次のようなことができます。

[HttpPost]
[Route("myRoute")]
public object SomeApiControllerMethod([FromBody] dynamic args){
   var stringValue = args.MyPropertyName.ToString();
   //do something with the string value.  If this is an int, we can int.Parse it, or if it's a string, we can just use it directly.
   //some more code here....
   return stringValue;
}
0
cloudstrifebro