2016-08-01 19 views
3

Ich kann eine Nicht-Leerfunktion von einem Lambda nennen, die zu einer Aktion zugewiesen wird (die einen Rückgabetyp void erwartet):Sind lambdas, die dem void delegate zugewiesen sind, den nicht void Rückgabetyp in C# verwerfen?

static bool foo() { return true; } 
... 
// Action action = foo; // This gives a compile error though. 
Action action =()=>foo(); // This compiles 

Zunächst ich diese während bemerkte ein Beispiel für List.ForEach() suchen. Ich könnte eine nicht-void-Funktion aus dem Lambda ausführen und es kompiliert.

Anfangs schien dies kontraintuitiv, und machte mich denken Sie nicht-Leere Funktionen auf einen void delegieren (void wirkende wie eine Art kontra) zuordnen kann, aber Action action = foo; funktionierte nicht.

Also jetzt nehme ich an, was passiert, ist, dass das Lambda ungültig wird, weil das der erwartete Rückgabetyp ist, so verwirft es den Rückgabetyp der non-void-Funktion, die es aufruft. Ist das korrekt?

Antwort

3

Ihr Beispiel

Action action =()=>foo(); 

ist wie jede andere Methode:

public void MyTestMethod() 
{ 
    // do something 
    foo(); 
    // do some more 
} 

Diese in C# völlig legal ist (obwohl einige statische Analysatoren würden Sie warnen, dass Sie nicht foo() ‚s verwenden Sie Rückgabewert).

zweites Beispiel:

action = foo; 

nicht funktioniert, weil foo selbst ein Verfahren mit einer Rücklauftyp ist und daher kann nur auf eine Variable Func<bool> Typen zugeordnet werden, aber nicht zu Action. Der Lambda () => foo() hat dagegen keinen Rückgabetyp und ist ein gültiger Action.

+0

Ja, das macht Sinn. Ich denke, es war nur die mathematisch-ähnliche Notation 'x => f (x)', die es auf den ersten Blick kontraproduktiv erscheinen lässt. Vielen Dank. – sashoalm

2

Nun, in dieser Codezeile:

Action action =()=> foo(); // This compiles 

Sie tatsächlich eine andere Methode erstellen, die Ihre Funktion läuft mit closure:

void AnonymousMethod() 
{ 
    foo(); 
} 

Um eine andere Methode zu einem Delegat zuweisen, Methode aufruft foo ist nicht das gleiche wie zuweisen foo Methode direkt zu delegieren. Und deshalb Codezeile:

Action action = foo; 

wird nicht kompiliert, da Action Delegierte hat Art von Leere und Methode zurückgeben foo nicht der Fall ist.