2017-03-23 2 views
0

Ich bin gespannt, ob das Folgende mit einer LINQ-Anweisung oder einem Lambda implementiert werden könnte. Ich bin neu bei beiden, also bin ich mir nicht ganz sicher, wie es codiert werden würde. Die Absicht ist eine Func <> Delegate, dass ich mehrere Rückrufe hinzufügen können, und sie alle als boolesche UND-Ausdruck aller Rückgabewerte ausgewertet werden. Eine bevorzugte Lösung würde es einem einzelnen Falsch ermöglichen, den Rest der Bewertungen kurzzuschließen. Ich habe dies in einem Brute-Force-Art und Weise umgesetzt, und der Code und Ausgabe sieht wie folgt aus:Wie mit LINQ oder Lambdas zu implementieren?

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 

Vielen Dank für alle Vorschläge.

+0

Während dies beim Thema hier ist; Sie können CodeReview.SE in Betracht ziehen, um Code-Fragen zu bearbeiten – BradleyDotNET

+0

Ich sehe dort keine rohe Gewalt. Brauchen Sie diese Zahlen auch wirklich? –

+0

Wenn Sie dies auf einfache Prädikate 'Func ' reduzieren, können Sie sie mit dem '&&' -Operator verketten und profitieren von seinem Kurzschlusszeichen. Aber ich bin mir nicht sicher, was Sie erreichen wollen. Was ist das größere Bild? –

Antwort

2

Ich würde persönlich eine benutzerdefinierte Erweiterung Methode erstellen und die Logik innerhalb (am wahrscheinlichsten mit einem foreach wie in Ihrer Probe, um Schließungen und Lambda Overhead zu vermeiden). Aber da Sie in LINQ-Lösung interessiert sind, die All Erweiterung Methode ist genau das, was Sie brauchen:

Ergebnis:

wahr wenn jedes Element der Quellensequenz besteht den Test in dem angegebenen Prädikat oder wenn die Sequenz leer ist; andernfalls falsch

Kurzschlüsse:

Die Aufzählung der Quelle gestoppt wird, sobald das Ergebnis festgestellt werden kann.

Equivalent Probe LINQ Code:

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

Ausgezeichnet! Vielen Dank! – rhoward99

Verwandte Themen