2012-02-17 8 views
1

私は式を初めて使用しています。私が作業している例でいくつか問題があります。複合式

私が達成しようとしているのは、2つ(または多く)の式が内部にある式を作成することです。例えば

public static Expression<Func<Occurrence, bool>> ReporterStartsWithAndClosed() 
{ 
    ParameterExpression occPar = Expression.Parameter(typeof(Occurrence)); 

    MemberExpression recorderProp = Expression.Property(occPar, "Reporter"); 
    MemberExpression fullnameProp = Expression.Property(recorderProp, "FullName"); 
    ConstantExpression letter = Expression.Constant("A", typeof(string)); 
    MethodInfo miStartsWith = typeof(string).GetMethod("StartsWith", new[] { typeof(string) }); 
    MethodCallExpression mCall = Expression.Call(fullnameProp, miStartsWith, letter); 

    MemberExpression oiProp = Expression.Property(occPar, "OccurrenceIncident"); 
    MemberExpression statusProp = Expression.Property(oiProp, "OccurreceIncidentStatus"); 
    MemberExpression nameProp = Expression.Property(statusProp, "Name"); 
    ConstantExpression name = Expression.Constant("Closed", typeof(string)); 
    BinaryExpression equalTo = Expression.Equal(name, nameProp); 

    return ...? 
} 

私が持っている問題は、私はこの方法のための正しい型を返すために、これらの式を組み合わせる方法です。私。 mCallとequalTo式のロジックを組み合わせる構文は何ですか?

私はBlockExpressionsを使用する必要がありましたが、これを動作させることはできませんでした。

ご協力いただければ幸いです。

おかげ デビッド

+0

私も)私はこれがExpresion.And(で行うことができます知っている、と述べている必要があります。私の質問は、あなたが多くの表現をしているならば、あなたは何をしているのかに沿っていました。これらを組み合わせるよりエレガントな方法はありますか? –

答えて

1

だから、論理を行うAND、式を生成するAndAlso()メソッドを使用します。次に、メソッドを完成させるために、この結合されたメソッドをラムダ式に入れたいと思うでしょう。

ちょっとしたヒントがありますが、宣言で型を書くのは避けたいです。すべてを読みにくくします。また、Call()のこのオーバーロードを使用してメソッドを名前で呼び出すことができます。メソッドのためにMethodInfoオブジェクトを取得する必要はありません。

私が(未テスト)このように一緒にそれを置くところ:

public static Expression<Func<Occurrence, bool>> ReporterStartsWithAndClosed(
    string letter = "A") 
{ 
    // occurrence => 
    //  occurrence.Reporter.FullName.StartsWith("A") 
    // 
    //  occurrence.OccurrenceIncident.OccurrenceIncidentStatus.Name == "Closed" 
    var occurrence = Expression.Parameter(typeof(Occurrence), "occurrence"); 

    var reporter = Expression.Property(occurrence, "Reporter"); 
    var fullName = Expression.Property(reporter, "FullName"); 
    var startsWithLetter = Expression.Call(
     fullName, 
     "StartsWith", 
     null, 
     Expression.Constant(letter, typeof(string)) 
    ); 

    var incident = Expression.Property(occurrence, "OccurrenceIncident"); 
    var status = Expression.Property(incident, "OccurrenceIncidentStatus"); 
    var name = Expression.Property(status, "Name"); 
    var equalsClosed = Expression.Equal(
     name, 
     Expression.Constant("Closed", typeof(string)) 
    ); 

    var body = Expression.AndAlso(startsWithLetter, equalsClosed); 
    return Expression.Lambda<Func<Occurrence, bool>>(body, occurrence); 
} 
関連する問題