2012-03-09 18 views
13

Fondamentalmente, c'è qualche differenza tra un'espressione di riga singola lambda e una dichiarazione lambda? Prendere il seguente codice, ad esempio:Espressione Lambda contro affermazione Lambda

private delegate void MyDelegate(); 

protected static void Main() 
{ 
    MyDelegate myDelegate1 =() => Console.WriteLine("Test 1"); 
    MyDelegate myDelegate2 =() => { Console.WriteLine("Test 2"); }; 

    myDelegate1(); 
    myDelegate2(); 

    Console.ReadKey(); 
} 

Mentre io preferisco il primo perché trovo le staffe di essere brutto, c'è qualcosa di diverso tra i due (oltre la parte ovvia circa richiedono staffe per le dichiarazioni multilinea) ?

+2

Sì, le parentesi. – Oded

risposta

13

È necessaria la dichiarazione lambda per i lambda multistato. Inoltre, le istruzioni lambda non sono supportate dai provider di espressioni come LINQ to SQL. Prima di .NET 4.0 .NET Framework non supportava gli alberi di espressione delle istruzioni. Questo è stato aggiunto in 4.0 ma per quanto ne so nessun provider lo usa.

Action myDelegate1 =() => Console.WriteLine("Test 1"); 
Expression<Action> myExpression =() => { Console.WriteLine("Test 2") }; //compile error unless you remove the { } 
myDelegate1(); 
Action myDelegate2 = myExpression.Compile(); 
myDelegate2(); 

Altrimenti sono uguali.

7

I due sono uguali: il primo è syntactic sugar al secondo ed entrambi verranno compilati allo stesso IL.

3

No, non vi sono differenze in questo esempio. Se il corpo del lambda è solo un'espressione, puoi rilasciare le parentesi. Tuttavia, una volta che lambda contiene più di un'espressione, in questo modo:

MyDelegate myDelegate2 =() => { 
    Console.WriteLine("Test 2");      
    Console.WriteLine("Test 2"); 
}; 

le parentesi sono obbligatorie.

10

Reflector per il salvataggio! Il codice smontato è simile al seguente:

private static void Main(string[] args) 
{ 
    MyDelegate myDelegate1 = delegate { 
     Console.WriteLine("Test 1"); 
    }; 
    MyDelegate myDelegate2 = delegate { 
     Console.WriteLine("Test 2"); 
    }; 
    myDelegate1(); 
    myDelegate2(); 
    Console.ReadKey(); 
} 

Quindi no, non v'è alcuna reale differenza tra i due. Siate felici.

2

Se il delegato restituisce un valore, è necessario return nella dichiarazione lambda come segue.

 Func<int, int, bool> foo = (x, y) => { return x == y; }; 
     Func<int, int, bool> goo = (x, y) => x == y; 
+0

I downvoters potrebbero non capire cosa fanno. :-) –

0

Lo stesso vale per l'esempio OP, ma dopo C# 6.0, che consente di utilizzare la stessa sintassi delle espressioni per definire metodi non-lambda normali all'interno delle classi. Ad esempio:

public static double AreaOfTriangle(double itsbase, double itsheight) 
{ 
    return itsbase * itsheight/2; 
} 

Il codice precedente frammento può essere scritta solo se il metodo può essere trasformato in una singola espressione. In breve, può essere usata la sintassi espressione lambda, ma non la sintassi lambda dell'istruzione.

public static double 
       AreaOfTrianglex(double itsbase, double itsheight) => itsbase * itsheight/2;