¿Puede una expresión lambda de C # tener más de una declaración?

131

¿Puede una expresión lambda de C # incluir más de una declaración?

(Editar: como se menciona en varias de las respuestas a continuación, esta pregunta originalmente preguntaba sobre "líneas" en lugar de "declaraciones").

paseena
fuente
17
Sí, puedes usar varias líneas. No me siento bien haciéndolo una respuesta completa.
Tesserex
1
@Tesserex: lo que no es una respuesta ... ¡tienes razón!
RQDQ
3
@RQDQ Debido a que es una pregunta de sí o no, no creo que sea digna del representante que generaría a partir de los votos a favor.
Tesserex

Respuestas:

195

Por supuesto:

List<String> items = new List<string>();

var results = items.Where(i => 
            {
                bool result;

                if (i == "THIS")
                    result = true;
                else if (i == "THAT")
                    result = true;
                else
                    result = false;

                return result;
            }
        );
RQDQ
fuente
31

(Supongo que realmente estás hablando de múltiples declaraciones en lugar de múltiples líneas).

Puede usar varias declaraciones en una expresión lambda usando llaves, pero solo la sintaxis que no usa llaves se puede convertir en un árbol de expresión:

// Valid
Func<int, int> a = x => x + 1;
Func<int, int> b = x => { return x + 1; };        
Expression<Func<int, int>> c = x => x + 1;

// Invalid
Expression<Func<int, int>> d = x => { return x + 1; };
Jon Skeet
fuente
1
Estoy tratando de entender por qué Func permite llaves y Expression no lo permite. De todos modos, Expression se cumplirá como Func. ¿Hay alguna forma de agregar lógica de línea múltiple al Árbol de expresión? Si no, ¿por qué hay que restringir eso?
Habeeb
8
@Habeeb: "De todos modos, Expression se cumplirá como Func" No siempre. La mayoría de las veces nunca se compila para un delegado, solo se examina como datos. Los árboles de expresión en .NET 4.0 obtuvieron la capacidad de incluir varias declaraciones a través de Expression.Block, pero el lenguaje C # no lo admite. Podría, pero eso requeriría más trabajo de diseño / implementación / prueba.
Jon Skeet
26

Puede poner tantas líneas nuevas como desee en una expresión lambda; C # ignora las nuevas líneas.

Probablemente quisiste preguntar sobre varias declaraciones .

Las declaraciones múltiples se pueden envolver entre llaves.

Ver la documentación .

SLaks
fuente
17
¿No sería más exacto decir que C # trata todos los espacios en blanco, incluidas las nuevas líneas, por igual? Suena un poco engañoso decir que ignora las nuevas líneas: hace que parezca que simplemente las elimina por completo, y podría dividir una palabra clave en una nueva línea o algo así.
Tesserex
6

Desde C # 7:

Declaración de una sola línea:

int expr(int x, int y) => x + y + 1; 

Declaración multilínea:

int expr(int x, int y) { int z = 8; return x + y + z + 1; };

aunque estas se llaman funciones locales, creo que esto se ve un poco más limpio que el siguiente y es efectivamente el mismo

Func<int, int, int> a = (x, y) => x + y + 1;

Func<int, int, int> b = (x, y) => { int z = 8; return x + y + z + 1; };
Gran jefe
fuente
4
Func<string, bool> test = (name) => 
{
   if (name == "yes") return true;
   else return false;
}
Gobierno
fuente
55
Func <string, bool> test = name => name == "yes";
asawyer
3
Polity está demostrando el formato de varias líneas solicitado por la pregunta, no entreteniendo sugerencias de golf. ¡Implementar su código inteligente lo haría "no una respuesta"!
Caius Jard el
0

Con c # 7.0 puedes usar así también

Public string ParentMethod(int i, int x){
    int calculation = (i*x);
    (string info, int result) InternalTuppleMethod(param1, param2)
    {
        var sum = (calculation + 5);
        return ("The calculation is", sum);
    }
}
jigar prajapati
fuente
0

Digamos que tienes una clase:

    public class Point
    {
        public int X { get; set; }
        public int Y { get; set; }
    }

Con el C # 7.0 dentro de esta clase, puede hacerlo incluso sin llaves:

Action<int, int> action = (x, y) => (_, _) = (X += x, Y += y);

y

Action<int, int> action = (x, y) => _ = (X += x, Y += y);

sería lo mismo que:

Action<int, int> action = (x, y) => { X += x; Y += y; };

Esto también puede ser útil si necesita escribir un método o constructor regular en una línea o cuando necesita más de una declaración / expresión para empaquetarse en una expresión:

public void Action(int x, int y) => (_, _) = (X += x, Y += y);

o

public void Action(int x, int y) => _ = (X += x, Y += y);

o

public void Action(int x, int y) => (X, Y) = (X + x, Y + y);

Más sobre la deconstrucción de tuplas en la documentación .

Konard
fuente