给定一个具有如此签名的方法:
MyMethod(params Expression<Func<Subscription, object>>[] fields)
这叫做:
MyMethod(x=> x.SomeProperty)
如何查看传递给MyMethod
的表达式?例如:
MyMethod(Expression<Func<Subscription, object>>[] fields) {
//using contains like this doesnt seem to work
if(fields.Contains(x=> x.SomeProperty)) {...}
}
答案 0 :(得分:2)
您可以实现ExpressionVisitor
,并在表达式树中查找名为SomeProperty
的属性:
internal class Finder : ExpressionVisitor {
private readonly string toFind;
public Finder(string toFind) {
this.toFind = toFind;
}
public bool IsFound { get; private set; }
protected override Expression VisitMember(MemberExpression node) {
IsFound |= node.Member.MemberType == MemberTypes.Property && node.Member.Name == toFind;
return base.VisitMember(node);
}
}
使用访客如下:
static void MyMethod(params Expression<Func<Program,object>>[] fields) {
foreach (var fieldExpr in fields) {
var finder = new Finder("Foo");
finder.Visit(fieldExpr);
if (finder.IsFound) {
Console.WriteLine("Expression {0} references 'Foo'", fieldExpr);
} else {
Console.WriteLine("Expression {0} does not reference 'Foo'", fieldExpr);
}
}
}
调用这样的方法
MyMethod(e => e.Foo, e => e.Bar, e => e.Bar != null ? e.Foo : e.Bar);
生成此输出:
Expression e => e.Foo references 'Foo'
Expression e => e.Bar does not reference 'Foo'
Expression e => IIF((e.Bar != null), e.Foo, e.Bar) references 'Foo'
答案 1 :(得分:0)
表达式非常通用。您可能首先需要过滤MemberExpression
的字段:
public static void MyMethod(params Expression<Func<Subscription, object>>[] fields)
{
var memberExpressions = fields
.Where(f => typeof(MemberExpression).IsAssignableFrom(f.Body.GetType()))
.Select(f => (MemberExpression)f.Body)
.ToList();
if (memberExpressions.Any(ex =>
ex.Member.MemberType == MemberTypes.Property &&
ex.Member.Name == "SomeProperty"))
{
Console.WriteLine("At least one of the fields expressions passed to this function were x => x.SomeProperty");
}
}