Получить значение динамического свойства 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"], однако я не тестировал.