2017-03-23 4 views
0

LINQステートメントまたはラムダを使用して以下を実装できるかどうか不思議です。私は両方に慣れていないので、どのようにコード化されるのかはよく分かりません。その目的は、Func <>代理人に複数のコールバックを追加できるようにし、それらのすべてをすべての戻り値のブールAND式として評価させることです。好ましい解決法は、単一の誤判定が残りの評価を短絡させることを可能にする。私はこれを強引に実装しており、コードと出力は次のようになります。LINQまたはlambdaを使用して実装する方法は?

using System; 
using System.Diagnostics; 
using System.Windows.Forms; 

namespace TestHarness 
{ 
    public partial class Form1 : Form 
    { 
     Func<bool, bool, bool, bool> validPosition; 

     public Form1() 
     { 
      InitializeComponent(); 
     } 

     private void button1_Click(object sender, EventArgs e) 
     { 
      validPosition += Func1; 
      validPosition += Func2; 
      validPosition += Func3; 

      Delegate[] delegates = validPosition.GetInvocationList(); 

      bool composite = true; 
      int i = 0; 

      foreach (Func<bool, bool, bool, bool> d in delegates) 
      { 
       composite = composite & d(false, true, true); 
       if (!composite) 
        break; 
       ++i; 
      } 
      Debug.WriteLine("Result: " + composite + "\tIterations: " + i); 

      composite = true; 
      i = 0; 
      foreach (Func<bool, bool, bool, bool> d in delegates) 
      { 
       composite = composite & d(true, false, true); 
       if (!composite) 
        break; 
       ++i; 
      } 
      Debug.WriteLine("Result: " + composite + "\tIterations: " + i); 

      composite = true; 
      i = 0; 
      foreach (Func<bool, bool, bool, bool> d in delegates) 
      { 
       composite = composite & d(true, true, false); 
       if (!composite) 
        break; 
       ++i; 
      } 
      Debug.WriteLine("Result: " + composite + "\tIterations: " + i); 

      composite = true; 
      i = 0; 
      foreach (Func<bool, bool, bool, bool> d in delegates) 
      { 
       composite = composite & d(true, true, true); 
       if (!composite) 
        break; 
       ++i; 
      } 
      Debug.WriteLine("Result: " + composite + "\tIterations: " + i); 
     } 

     bool Func1(bool a, bool b, bool c) 
     { 
      return a; 
     } 
     bool Func2(bool a, bool b, bool c) 
     { 
      return b; 
     } 
     bool Func3(bool a, bool b, bool c) 
     { 
      return c; 
     } 
    } 
} 

Output: 

Result: False Iterations: 0 
Result: False Iterations: 1 
Result: False Iterations: 2 
Result: True Iterations: 3 

ありがとうございます。

+0

これはここにトピックですが。 CodeReview.SEに行くことを検討してもよいでしょう。 – BradleyDotNET

+0

そこには何の力もありません。また、本当にこれらのカウントが必要ですか? –

+0

単純な述語 'Func 'にこれを減らすと、それらを '&&'演算子で連鎖させて、その短絡文字の恩恵を受けることができます。しかし、私はあなたが達成しようとしていることをよく分かりません。より大きな写真は何ですか? –

答えて

2

私は個人的にカスタム拡張メソッドを作成し、内部にロジックを入れます(おそらく、クロージャとラムダオーバヘッドを避けるためにサンプル内にforeachを使用しています)。しかし、あなたはLINQソリューションに興味を持っているので、All拡張メソッドは、正確に何が必要です:

結果:

ソースシーケンスのすべての要素が指定された述語でテストに合格した場合、またはシーケンスが空の場合。そうでない場合は、

短絡:ソースの

列挙は、すぐに結果を決定することができるように停止されます。

同等のサンプルLINQコード:

var delegates = validPosition.GetInvocationList().Cast<Func<bool, bool, bool, bool>>(); 

Debug.WriteLine("Result: " + delegates.All(d => d(false, true, true))); 
Debug.WriteLine("Result: " + delegates.All(d => d(true, false, true))); 
Debug.WriteLine("Result: " + delegates.All(d => d(true, true, false))); 
Debug.WriteLine("Result: " + delegates.All(d => d(true, true, true))); 
+0

優秀!ありがとうございました! – rhoward99

関連する問題