2012-03-09 21 views
13

Fundamentalmente, ¿hay alguna diferencia entre una expresión de una sola línea lambda y una declaración lambda? Tome el siguiente código, por ejemplo:Expresión Lambda versus Statement 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(); 
} 

Aunque yo prefiero la primera porque encuentro los soportes que ser feo, ¿hay algo diferente entre los dos (además de la parte obvia acerca requieren soportes para las declaraciones de varias líneas) ?

+2

Sí, los corchetes. – Oded

Respuesta

13

Necesita la declaración lambda para lambdas de instrucciones múltiples. Además, las declaraciones lambdas no son compatibles con los proveedores de expresiones como LINQ to SQL. Antes de .NET 4.0 .NET Framework no tenía soporte para árboles de expresiones de sentencias. Esto fue agregado en 4.0, pero hasta donde sé, ningún proveedor 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(); 

De lo contrario, son los mismos.

7

Los dos son iguales - el primero es syntactic sugar al segundo y ambos compilarán a la misma IL.

3

No, no hay diferencia en este ejemplo. Si el cuerpo de la lambda es solo una expresión, puedes soltar los corchetes. Sin embargo, una vez que el lambda contiene más de una expresión, haga lo siguiente:

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

los soportes son obligatorios.

10

Reflector al rescate! El código desensamblado tiene el siguiente aspecto:

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

Así que no, no hay ninguna diferencia real entre los dos. Sea feliz.

2

Si el delegado devuelve un valor, return es necesario en la instrucción lambda de la siguiente manera.

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

Downvoters podría no entender lo que hacen. :-) –

0

mismo para el ejemplo OP, pero después de C# 6.0, lo que permite utilizar misma sintaxis de expresión para definir métodos no lambda normales dentro de una clase. Por ejemplo:

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

El código anterior fragmento puede escribirse sólo si el método se puede convertir en una sola expresión. En resumen, se puede usar la expresión sintaxis lambda, pero no la declaración sintaxis lambda.

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