Получить значение динамического свойства c# через строку
Я хотел бы получить доступ к значению элемента dynamic
свойство c# со строкой:
dynamic d = new { value1 = "some", value2 = "random", value3 = "value" };
как я могу получить значение d.value2 ("random"), если у меня есть только" value2 " в виде строки? В javascript я мог бы сделать d ["value2"] для доступа к значению ("random"), но я не уверен, как это сделать с c# и отражением. Ближе всего я подошел к этому:
d.GetType().GetProperty("value2")
... но я не знаю, как получить текущее значение этого.
как всегда, спасибо за ваш помогите!
8 ответов
как только у вас есть свой PropertyInfo
(от GetProperty
), вам нужно позвонить GetValue
и передайте экземпляр, из которого вы хотите получить значение. В вашем случае:
d.GetType().GetProperty("value2").GetValue(d, null);
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. Работает также для динамических типов и частных свойств и полей.
редактировать: в то время как этот подход работает, есть почти 20× более быстрый метод из Microsoft.На языке VisualBasic.dll файлы сборка:
public static object GetProperty(object target, string name)
{
return Microsoft.VisualBasic.CompilerServices.Versioned.CallByName(target, name, CallType.Get);
}
Dynamitey является открытым исходным кодом .net std
библиотека, которую вы называете dynamic
ключевое слово, но используя строку a для имени свойства, а не компилятор делает это за вас, и это заканчивается равно отражению speedwise (что не так быстро, как использование динамического ключевого слова, но это связано с дополнительными накладными расходами на кэширование динамически, где компилятор кэширует статически).
Dynamic.InvokeGet(d,"value2");
большую часть времени, когда вы просите динамический объект, вы получаете ExpandoObject (не в анонимном, но статически типизированном примере вопроса выше, но вы упоминаете JavaScript и мой выбранный парсер JSON JsonFx, например, генерирует ExpandoObjects).
Если ваша динамика на самом деле является ExpandoObject, вы можете избежать отражения, приведя его к IDictionary, как описано в http://msdn.microsoft.com/en-gb/library/system.dynamic.expandoobject.aspx.
после того, как вы бросили IDictionary, у вас есть доступ к полезным методам, таким как .Изделие и. ContainsKey
самый простой способ получения как 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");
д'.Метод gettype().GetProperty ("value2")
возвращает объект PropertyInfo.
а
propertyInfo.GetValue(d)
вот как я получил значение значения свойства динамического:
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)
{
}
}
GetProperty/GetValue не работает для данных Json, он всегда генерирует нулевое исключение, однако вы можете попробовать этот подход:
сериализация объекта с помощью JsonConvert:
var z = Newtonsoft.Json.JsonConvert.DeserializeObject(Convert.ToString(request));
затем получите доступ к нему напрямую, возвращая его в строку:
var pn = (string)z["DynamicFieldName"];
Он может работать прямо применяя преобразования.ToString (request)["DynamicFieldName"], однако я не тестировал.