2014-07-07 8 views
13

Ich bin neu in C#, aber nach meinem Verständnis sollte dieser Code funktionieren. Warum funktioniert es nicht?Lambda Ausdruck in 'If' Anweisung Zustand

Dies ist ein Beispiel für meinen Code.

List<Car> cars // This has many cars initialized in it already 
if (() => { 
    foreach(Car car in cars){ 
     if (car.door == null) return true; 
    } 
}){then .......} 

Einfach gesagt, alles, was ich der Code will die if Anweisung, wenn jedes Auto zu tun ist, läuft nicht eine Tür hat.

Nach dem Versuch bekomme ich diesen Fehler zu kompilieren:

Cannot convert lambda expression to type 'bool' because it is not a delegate type.

+0

Sie sind nicht einmal die richtige Lambda-Syntax. Es wäre '() => {' ..., not '() = {' ... Natürlich würde es nicht funktionieren, wenn Sie * es benutzen würden, aber das ist eine andere Geschichte. –

Antwort

33

Wenn Sie, wenn jedes Auto überprüfen wollen dann einfach Enumerable.Any verwenden keine Tür - es bestimmt, ob jedes Element einer Sequenz eine Bedingung erfüllt:

if (cars.Any(c => c.door == null)) 
    // then ... 

Just for fun: Sie sollten Lambda ausführen in boolean Ergebnis zu erhalten, wenn die Bedingung (aber für diesen Fall verwenden, um all)

Func<bool> anyCarDoesNotHaveDoor =() => { 
    foreach(var car in cars) 
     if (car.door == null) 
      return true; 
    return false; 
}; 

if (anyCarDoesNotHaveDoor()) 
    // then ... 

Ich habe lokale Variable eingeführt, um die Dinge klarer zu machen. Aber natürlich können Sie dieses Puzzlespiel komplizierter machen

if (new Func<bool>(() => { 
     foreach(var car in cars) 
      if (car.door == null) 
       return true; 
     return false; })()) 
    // then ...  
+0

Nur um sicher zu gehen, hättest du das machen können. if (Func () => {}) – user3813249

+4

@ user3813249, Sie müssen immer noch den Delegaten anrufen. Ein Delegat an und für sich ergibt für eine 'if'-Aussage keinen Sinn. – BradleyDotNET

+2

@ user3813249 Func Delegat sollte Booleschen Wert zurückgeben, so können Sie nicht einfach leeren Körper zuweisen, wie Sie mit "Action" tun können –

8

Nun, der Fehler sagt alles. Eine if-Anweisung erwartet einen booleschen Ausdruck, der ein Delegat nicht ist. Wenn Sie den Delegierten anrufen würden (vorausgesetzt, er gab bool zurück), wäre es Ihnen gut. Allerdings kann if es nicht nennen.

Der einfache Weg, dies zu tun ist mit der Methode Any LINQ-Erweiterung:

if (cars.Any(car => car.door == null)) 

Die Any Methode kennt den Lambda-Ausdruck auf jedem Mitglied der Sammlung tatsächlich aufzurufen, und gibt ein bool. Dies macht es zu einem gültigen booleschen Ausdruck für die if-Anweisung.

+1

Dies scheint eine irreführende Erklärung. Ein Delegat * ist * ein Ausdruck, wie Sie sehen, indem Sie ihn einen Moment später als Lambda-Ausdruck bezeichnen. Es ist nur so, dass 'if' seine Bedingung als * Boolean * -Ausdruck - einen vom Typ' bool' - verlangt. Lambdas sind vom Typ 'Func ' für einige Rückgabetypen 'T' und können daher diese Anforderung nicht erfüllen. (Sie können auch Ausdrucksbaumtypen sein, abhängig vom Schlussfolgerung aus dem Kontext ihrer Verwendung, aber sie können nicht "bool" sein.) – 00dani

+0

@ 00Davo Sie haben Recht, das hätte besser formuliert werden können. Ich werde bearbeiten und sehen, ob ich es aufräumen kann. – BradleyDotNET

2

Falls Sie tatsächlich ohne Türen etwas zu Autos tun:

foreach (var car in cars.Where(car => car.door == null)) { 
    car.door = <whatever>; 
}