开发者

Can I use Expression<Func<T, bool>> and reliably see which properties are referenced in the Func<T, bool>?

开发者 https://www.devze.com 2023-01-15 11:31 出处:网络
I\'m writing something in the flavour of Enumerable.Where in that takes a predicate of the form Func<T, bool>. If the underlying T implements INotifyPropertyChanged, I\'d like to be a bit more i

I'm writing something in the flavour of Enumerable.Where in that takes a predicate of the form Func<T, bool>. If the underlying T implements INotifyPropertyChanged, I'd like to be a bit more intelligent about re-evaluating the predicate.

I'm thinking about changing it to use Expression<Func<T, bool>>, and then using the expression tree to find out which properties are used in开发者_开发知识库 the predicate. Then I can have my PropertyChanged handler be a bit more intelligent.

My question: is this feasible? If the predicate's simple (e.g. x => x.Age > 18), then the Expression seems to have everything I need in it. Are there scenarios where I won't be able to see which properties are referenced?


Yes, you'll be able to see everything directly referenced. Of course, if someone passes

x => ComputeAge(x) > 18

then you won't necessarily know that ComputeAge refers to the Age property.

The expression tree will be an accurate representation of exactly what's in the lambda expression.


Small code example of a visitor that would find directly referenced properties.

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);
0

精彩评论

暂无评论...
验证码 换一张
取 消