Can I use Expression<Func<T, bool>> and reliably see which properties are referenced in the Func<T, bool>?
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);
精彩评论