Получить значение свойства из динамического объекта С# по строке (отражение?)
Предположим, что у меня есть динамическая переменная:
dynamic d = *something*
Теперь что-то создает свойства для d
, которые я имею, с другой стороны, из массива строк:
string[] strarray = { 'property1','property2',..... }
Я не знаю имена свойств заранее.
Как в коде, после создания d
и strarray извлекается из БД, могу ли я получить значения?
Я хочу получить d.property1 , d.property2
.
Я вижу, что у объекта есть внутренний словарь _dictionary
, содержащий ключи и значения, как их получить?
Ответы
Ответ 1
Я не знаю, есть ли более элегантный способ с динамически создаваемыми объектами, но с использованием простого старого отражения должно работать:
var nameOfProperty = "property1";
var propertyInfo = myObject.GetType().GetProperty(nameOfProperty);
var value = propertyInfo.GetValue(myObject, null);
GetProperty
вернет null
, если тип myObject
не содержит общедоступного свойства с этим именем.
EDIT. Если объект не является "обычным" объектом, а чем-то реализует IDynamicMetaObjectProvider
, этот подход не будет работать. Пожалуйста, посмотрите на этот вопрос:
Ответ 2
Это даст вам все имена и значения свойств, определенные в вашей динамической переменной.
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);
}
Ответ 3
Надеюсь, это поможет вам:
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);
}
}
Ответ 4
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 в динамический объект С#?
+ сделать переменную _dictionary от "private readonly" до общедоступной в коде там
Ответ 5
Вы видели класс ExpandoObject?
Непосредственно из Описание MSDN: "Представляет объект, члены которого могут быть динамически добавлены и удалены во время выполнения".
С его помощью вы можете написать код следующим образом:
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
((IDictionary<String, Object>)employee).Remove("Name");
Ответ 6
Если d был создан Newtonsoft, вы можете использовать это для чтения имен и значений свойств:
foreach (JProperty property in d)
{
DoSomething(property.Name, property.Value);
}
Ответ 7
Думал, что это может помочь кому-то в будущем.
Если вы уже знаете имя свойства, вы можете сделать что-то вроде следующего:
[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 a string, we can just use it directly.
//some more code here....
return stringValue;
}
Ответ 8
Можете ли вы попробовать как:
d?.property1 , d?.property2
Я тестировал и работал с .netcore 2.1
Ответ 9
Вы можете использовать " dynamicObject.PropertyName.Value
", чтобы получить значение динамического свойства напрямую.
Пример:
d.property11.Value
Ответ 10
Используйте следующий код, чтобы получить Имя и Значение свойства динамического объекта.
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
}