Получить значение свойства из динамического объекта C # по строке (отражение?) - PullRequest
64 голосов
/ 26 декабря 2011

Предположим, у меня есть динамическая переменная:

dynamic d = *something*

Теперь что-то создает свойства для d, которые у меня есть, с другой стороны, из строкового массива:

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

Я заранее не знаю имен свойств.

Как в коде после создания d и извлечения стратрей из БД можно получить значения?

Я хочу получить d.property1 , d.property2.

Я вижу, что у объекта есть внутренний словарь _dictionary, который содержит ключи и значения, как мне их получить?

Ответы [ 10 ]

92 голосов
/ 26 декабря 2011

Я не знаю, есть ли более элегантный способ с динамически созданными объектами, но использование простого старого отражения должно работать:

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

GetProperty вернет null, если тип myObject не содержит открытого свойства с этим именем.


EDIT : Если объект не является "обычным" объектом, а реализует IDynamicMetaObjectProvider, этот подход не будет работать. Пожалуйста, взгляните на этот вопрос:

25 голосов
/ 26 декабря 2011

Это даст вам все имена свойств и значения, определенные в вашей динамической переменной.

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);
}
20 голосов
/ 23 декабря 2012

Надеюсь, это поможет вам:

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);
    }
}
5 голосов
/ 26 декабря 2011
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 #? + сделать переменную _dictionary из "private readonly" в public в коде там

4 голосов
/ 09 ноября 2014

Вы видели ExpandoObject class?

Непосредственно из MSDN-описание : "Представляет объект, члены которого могут динамически добавляться и удаляться во время выполнения."

С его помощью вы можете написать такой код:

dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
((IDictionary<String, Object>)employee).Remove("Name");
3 голосов
/ 04 февраля 2018

ЕСЛИ d был создан Newtonsoft, вы можете использовать это для чтения имен и значений свойств:

    foreach (JProperty property in d)
    {
        DoSomething(property.Name, property.Value);
    }
0 голосов
/ 06 мая 2019

Вы можете использовать "dynamicObject.PropertyName.Value" для непосредственного получения значения динамического свойства.

Пример :

d.property11.Value
0 голосов
/ 01 мая 2019

Можете ли вы попробовать как:

d?.property1 , d?.property2

Я тестировал и работал с .netcore 2.1

0 голосов
/ 12 апреля 2018

Используйте следующий код, чтобы получить Имя и Значение свойства динамического объекта.

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
 }
0 голосов
/ 31 марта 2017

Думал, что это может помочь кому-то в будущем.

Если вы уже знаете имя свойства, вы можете сделать что-то вроде следующего:

[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;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...