2017-05-12 7 views
0

が含まれていますか?例:チェック式の場合はそうのようなシグネチャを持つメソッドを与えられた特定のプロパティ

MyMethod(Expression<Func<Subscription, object>>[] fields) { 
    //using contains like this doesnt seem to work 
    if(fields.Contains(x=> x.SomeProperty)) {...} 
} 
+3

あなたの質問は、誤った前提に構築されています。 「式」は必ずしもプロパティーアクセス操作である必要はなく、リテラル値または別のタイプの式であってもよい。 'MyMethod(x => this.SomeDelegate(x).SomeExtensionMethod(' MyMethod(x => 5 + 2) '、' MyMethod(x => null) '、または別の式の一部として名前で渡されたもの) )?? 123) ' – Dai

+0

@Daiありがとう。私の例と同様のアプローチを達成するために、別のパラメータの署名を提案していますか?注:このユースケースでは、 'x => 5 + 2'を実行する人々について心配する必要はありません。最終目標は、厳密に型指定された方法で指定したいオブジェクトのどのプロパティをユーザーが簡単に指定できるようにすることです。 –

答えて

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"); 
    } 
} 
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' 

Demo.

関連する問題