Как получить динамический / поздний доступ к свойствам? - PullRequest
1 голос
/ 07 сентября 2010

Я хотел бы реализовать метод, который позволяет мне получить доступ к свойству неизвестного / анонимного объекта (-graph) с поздней привязкой / динамическим способом (я даже не знаю, как правильно его вызвать).

Вот пример того, чего я хотел бы достичь:

// setup an anonymous object
var a = new { B = new { C = new { I = 33 } } };

// now get the value of a.B.C.I in a late-bound way
var i = Get(a, "B.C.I"); 

А вот простая реализация с использованием «классического» отражения:

public static object Get(object obj, string expression)
{
    foreach (var name in expression.Split('.'))
    {
        var property = obj.GetType().GetProperty(name);
        obj = property.GetValue(obj, null);
    }
    return obj;
}

Какие другие вариантыу меня есть с C # / .NET 4, чтобы реализовать нечто подобное, как показано выше, но, возможно, проще, более производительным и т. д.?

Может быть, есть способы достичь того же, что позволило бы мне указать expression используя лямбда-выражение вместо строки?Могут ли деревья выражений быть полезными в любом случае (например, как показано в в этом вопросе )?

Обновление : объект и выражение передаются в мой код через сетьсервисный звонок.Вот почему я использовал object и string в своем методе Get().

Ответы [ 2 ]

2 голосов
/ 07 сентября 2010

У вас на самом деле есть только выражение в виде строки? Известно ли во время компиляции, что сами типы неизвестны (или их трудно выразить)? Если так:

dynamic d = a;
int i = d.B.C.I;

Если у вас действительно есть только строка (например, введенные пользователем данные), которая делает жизнь намного сложнее, и ни одна из функций C # 4 вам не поможет. Вы можете оценить его как скрипт IronPython или что-то в этом роде ...

РЕДАКТИРОВАТЬ: Хорошо, после обновления звучит, как будто вы находитесь в последней ситуации - в этом случае, я не знаю более приятного способа, чем использование отражения. Может помочь некоторая встроенная привязка свойств, созданная для пользовательского интерфейса, но я не знаю, как правильно получить к ней доступ.

1 голос
/ 07 сентября 2010

Если вы хотите использовать стиль C #, вы можете использовать Mono-компилятор в качестве службы из вашего приложения.Я описываю, как это сделать здесь: Моно-компилятор как услуга (MCS)

В качестве альтернативного подхода вы можете использовать отражение, чтобы поместить все свойства вашего объекта в ExpandoObject, а затем использовать его.как словарь (потому что ExpandoObject реализует IDictionary).В качестве альтернативы вы можете использовать JSON.NET и вызвать JObject.FromObject, что превратит обычный объект в объект JObject, доступный в стиле словаря (и в качестве дополнительного преимущества имеет поддержку рекурсивного графа).Наконец, вы можете использовать тот же подход, чтобы сбросить ваш объект в словарь словарей.

...