Я хотел бы получить доступ к значению свойства dynamic
С# со строкой:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
Как я могу получить значение d.value2 ( "random" ), если у меня есть только "value2" в виде строки? В javascript я мог бы сделать d [ "value2" ] для доступа к значению ( "случайный" ), но я не уверен, как это сделать с помощью С# и отражения. Самое близкое, что я пришел, это:
d.GetType().GetProperty("value2")
... но я не знаю, как получить от него фактическое значение.
Как всегда, спасибо за вашу помощь!
Ответ 1
Как только у вас есть PropertyInfo
(от GetProperty
), вам нужно позвонить GetValue
и передать экземпляр, из которого вы хотите получить значение. В вашем случае:
d.GetType().GetProperty("value2").GetValue(d, null);
Ответ 2
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);
}
Ответ 3
Dynamitey - это библиотека .net std
с открытым исходным кодом, которая позволяет вам называть ее как ключевое слово dynamic
, но используя строку для имени свойства, а не компилятор, который делает это за вас, и в итоге она становится равной отражению по скорости (что не так быстро, как использование динамического ключевого слова, но это связано с дополнительными издержками динамического кэширования, когда компилятор статически кэширует).
Dynamic.InvokeGet(d,"value2");
Ответ 4
Самый простой способ получения как в 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");
Ответ 5
В большинстве случаев, когда вы запрашиваете динамический объект, вы получаете ExpandoObject (не в вопросе анонимного, но статически типизированного примера выше, но вы упомянете JavaScript и мой выбранный JSON-анализатор JsonFx, например, генерирует ExpandoObjects).
Если ваша динамика на самом деле является ExpandoObject, вы можете избежать отражения, отбросив ее в IDictionary, как описано в http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx.
После того, как вы передали IDictionary, у вас есть доступ к полезным методам, например .Item и .ContainsKey
Ответ 6
d.GetType(). GetProperty ( "значение2" )
возвращает объект PropertyInfo.
Итак, тогда
propertyInfo.GetValue(d)
Ответ 7
Так я получил значение свойства dinamic:
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)
{
}
}
Ответ 8
GetProperty/GetValue не работает для данных Json, он всегда генерирует нулевое исключение, однако вы можете попробовать этот подход:
Сериализовать свой объект с помощью JsonConvert:
var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));
Затем перейдите к нему напрямую, вернув его в строку:
var pn = (string)z["DynamicFieldName"];
Он может работать прямо, применяя Convert.ToString(запрос) [ "DynamicFieldName" ], однако я не тестировал.
Ответ 9
Чтобы получить свойства из динамического документа, когда .GetType()
возвращает null
, попробуйте это:
var keyValuePairs = ((System.Collections.Generic.IDictionary<string, object>)doc);
var val = keyValuePairs["propertyName"].ToObject<YourModel>;