您可以實現一個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'
Demo.
你的問題是建立在一個不正確的假設。 「表達式」不一定只是屬性訪問操作,它可以是文字值或其他類型的表達,例如, MyMethod(x => 5 + 2)','MyMethod(x => null)'或者作爲另一個表達式的名字傳入的東西:'MyMethod(x => this.SomeDelegate(x).SomeExtensionMethod )?? 123)' – Dai
@戴謝謝。你是否建議使用不同的參數簽名來實現與我的示例類似的方法?注意:這個用例不需要擔心人們在執行'x => 5 + 2''。最終目標僅僅是讓用戶輕鬆指定他們想要以強類型方式指定的對象上的哪些屬性。 –