问题
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?
回答1:
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.
回答2:
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);
来源:https://stackoverflow.com/questions/3665980/can-i-use-expressionfunct-bool-and-reliably-see-which-properties-are-refere