Используется ли отражение при извлечении информации из выражения linq?

У меня есть следующий метод расширения:

public static string ToPropertyName<T,E>(this Expression<Func<E, T>> propertyExpression)
{
    if (propertyExpression == null)
        return null;

    string propName;
    MemberExpression propRef = (propertyExpression.Body as MemberExpression);
    UnaryExpression propVal = null;

    // -- handle ref types
    if (propRef != null)
        propName = propRef.Member.Name;
    else
    {
        // -- handle value types
        propVal = propertyExpression.Body as UnaryExpression;
        if (propVal == null)
            throw new ArgumentException("The property parameter does not point to a property", "property");
        propName = ((MemberExpression)propVal.Operand).Member.Name;
    }

    return propName;
}

Я использую выражение linq при передаче имен свойств вместо строк, чтобы обеспечить строгую типизацию, и я использую эту функцию для получения имени свойства в виде строки. Использует ли этот метод отражение?

Я спрашиваю, почему этот метод довольно часто используется в нашем коде, и я хочу, чтобы он был достаточно быстрым.


person Mel    schedule 06.07.2012    source источник
comment
Также см. stackoverflow.com/questions/4803272/   -  person nawfal    schedule 03.02.2013
comment


Ответы (2)


Насколько мне известно, рефлексия не задействована в том смысле, что за кулисами происходит какой-то вид самоанализа динамического типа. Однако типы из System.Reflection, такие как Type или PropertyInfo, используются вместе с типами из пространства имен System.Linq.Expressions. Они используются компилятором только для описания любого Func<T,E>, переданного вашему методу, как абстрактного синтаксического дерева (AST). Поскольку это преобразование из Func<T,E> в дерево выражений выполняется компилятором, а не во время выполнения, описываются только статические аспекты лямбда.

Однако помните, что построение этого дерева выражений (сложный граф объектов) из лямбда-выражения во время выполнения может занять несколько больше времени, чем простая передача строки имени свойства (один объект), просто потому, что необходимо создать больше объектов (число зависит от сложности лямбда-выражения, переданного вашему методу), но, опять же, проверка динамического типа à la someObject.GetType() не выполняется.

Пример:

В этой статье MSDN показано, что следующее лямбда-выражение:

Expression<Func<int, bool>> lambda1 = num => num < 5;

трансформируется компилятором во что-то подобное:

ParameterExpression numParam = Expression.Parameter(typeof(int), "num");
ConstantExpression five = Expression.Constant(5, typeof(int));
BinaryExpression numLessThanFive = Expression.LessThan(numParam, five);
Expression<Func<int, bool>> lambda1 =
    Expression.Lambda<Func<int, bool>>(
        numLessThanFive,
        new ParameterExpression[] { numParam });

Больше ничего не происходит. Итак, это граф объекта, который затем может быть передан в ваш метод.

person stakx - no longer contributing    schedule 06.07.2012

Поскольку вы называете метод ToPropertyName, я полагаю, вы пытаетесь получить типизированное имя некоторого конкретного свойства класса. Вы тестировали Expression<Func<E, T>> подход? Стоимость создания выражения намного больше, и, поскольку ваш метод статичен, я вижу, что вы также не кэшируете выражение члена. Другими словами, даже если в выражении не используется отражение, цена может быть высокой. См. Этот вопрос: Как сделать вы получаете имя свойства C # в виде строки с отражением? где у вас есть другой подход:

public static string GetName<T>(this T item) where T : class
{
    if (item == null)
        return string.Empty;

    return typeof(T).GetProperties()[0].Name;
}

Вы можете использовать его для получения имени свойства или переменной, например:

new { property }.GetName();

Для дальнейшего ускорения вам необходимо кэшировать информацию о членах. Если то, что у вас есть, абсолютно Func<E, T>, то ваш подход подходит. См. Также следующее: отражение на основе лямбда-выражения против нормального отражения

Связанный вопрос: Получите все имена свойств и соответствующие значения в словарь

person nawfal    schedule 17.04.2013