Могу ли я использовать Expression <Func <T, bool >> и надежно увидеть, на какие свойства ссылаются в Func <T, bool>? - PullRequest
1 голос
/ 08 сентября 2010

Я пишу что-то со вкусом Enumerable.Where, что принимает предикат вида Func<T, bool>.Если базовый T реализует INotifyPropertyChanged, я бы хотел быть более умным в отношении переоценки предиката.

Я подумываю изменить его на Expression<Func<T, bool>>, а затемдерево выражений, чтобы узнать, какие свойства используются в предикате.Тогда я могу сделать так, чтобы мой обработчик PropertyChanged стал немного более интеллектуальным.

Мой вопрос: возможно ли это?Если предикат простой (например, x => x.Age > 18), то, похоже, в Expression есть все, что мне нужно.Существуют ли сценарии, в которых я не смогу увидеть, на какие свойства ссылаются?

Ответы [ 2 ]

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

Да, вы сможете увидеть все ссылки напрямую .Конечно, если кто-то передает

x => ComputeAge(x) > 18

, вы не обязательно будете знать, что ComputeAge относится к свойству Age.

Дерево выражений будет точным представлением точночто в лямбда-выражении.

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

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

public class PropertyAccessFinder : ExpressionVisitor {
    private readonly HashSet<PropertyInfo> _properties = new HashSet<PropertyInfo>();

    public IEnumerable<PropertyInfo> Properties {
        get { return _properties; }
    }

    protected override Expression VisitMember(MemberExpression node) {
        var property = node.Member as PropertyInfo;
        if (property != null)
            _properties.Add(property);

        return base.VisitMember(node);
    }
}

// Usage:
var visitor = new PropertyAccessFinder();
visitor.Visit(predicate);
foreach(var prop in visitor.Properties)
    Console.WriteLine(prop.Name);
...