MemberExpression to MemberExpression [] - PullRequest
       33

MemberExpression to MemberExpression []

2 голосов
/ 17 декабря 2010

Цель состоит в том, чтобы получить массив MemberExpressions из двух LambdaExpressions. Первый может быть преобразован в метод MethodCallExpression, который возвращает экземпляр объекта (Expression<Func<T>>). Второе лямбда-выражение получит результат скомпилированного первого выражения и вернет вложенный член (Expression<Func<T,TMember>>). Можно предположить, что второе лямбда-выражение будет вызывать только вложенные свойства, но может выполнять несколько из этих вызовов.

Итак, подпись метода, который я пытаюсь создать:

MemberExpression[] GetMemberExpressionArray<T,TValue>(Expression<Func<T>> instanceExpression, Expression<Func<T,TValue>> nestedMemberExpression)

где nestedMemberExpression будет принимать аргумент вида

parent => parent.ChildProperty.GrandChildProperty

и результирующий массив представляет MemberAccess от parent до ChildProperty и от значения ChildProperty до GrandChildProperty.

Я уже вернул последний MemberExpression, используя следующий метод расширения.

public static MemberExpression GetMemberExpression<T, TValue>(Expression<Func<T, TValue>> expression)
{
    if (expression == null)
    {
        return null;
    }
    if (expression.Body is MemberExpression)
    {
        return (MemberExpression)expression.Body;
    }
    if (expression.Body is UnaryExpression)
    {
        var operand = ((UnaryExpression)expression.Body).Operand;
        if (operand is MemberExpression)
        {
            return (MemberExpression)operand;
        }
        if (operand is MethodCallExpression)
        {
            return ((MethodCallExpression)operand).Object as MemberExpression;
        }
    }
    return null;
} 

Теперь я знаю, что есть несколько способов сделать это. Наиболее интуитивно понятным для меня было бы перебрать свойство .Expression, чтобы получить первое выражение и захватить ссылки на каждое MemberExpression по пути. Это может быть лучший способ сделать это, но это не так. Я не очень хорошо знаком с затратами на производительность, которые я получаю от использования таких выражений. Я знаю, что MemberExpression имеет MemberInfo, и это отражение должно снизить производительность.

Я пытался найти информацию о выражениях, но мои ресурсы были очень ограничены в том, что я нашел.

Буду признателен за любые советы о том, как выполнить эту задачу (и задачу такого типа в целом) с оптимальной производительностью и надежностью.

1 Ответ

1 голос
/ 10 февраля 2011

Я не уверен, почему это было помечено производительность , но самый простой способ, которым я могу придумать для извлечения выражений-членов из дерева, это подкласс ExpressionVisitor. Это должно быть намного проще, чем вручную писать логику для «расширения» различных типов выражений и обхода дерева.

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

  1. Каждое выражение-член фиксируется.
  2. Его дети посещают.

Я думаю, что это будет выглядеть примерно так:

protected override Expression VisitMember(MemberExpression node)
{
    _myListOfMemberExpressions.Add(node);
    return base.VisitMember(node);
}

Мне немного неясно насчет остальной части вашей задачи; Похоже, вы хотите переписать выражений параметров, в этом случае вы можете посмотреть этот ответ от Марка Гравелла.

...