Uma expressão lambda C # pode ter mais de uma instrução?

131

Uma expressão lambda C # pode incluir mais de uma instrução?

(Edit: Como mencionado em várias das respostas abaixo, esta pergunta foi feita originalmente sobre "linhas" em vez de "declarações".)

paseena
fonte
17
Sim, você pode usar várias linhas. Não me sinto bem em fazer uma resposta completa.
Tesserex
1
@Tesserex - o que não faz dela uma resposta ... você está certo!
RQDQ
3
@RQDQ Por se tratar de uma pergunta de sim ou não, não acho que valha a pena o representante que isso geraria a partir dos upvotes.
Tesserex

Respostas:

195

Certo:

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
fonte
31

(Suponho que você esteja realmente falando sobre várias declarações em vez de várias linhas).

Você pode usar várias instruções em uma expressão lambda usando chaves, mas apenas a sintaxe que não usa chaves pode ser convertida em uma árvore de expressões:

// 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
fonte
1
Estou tentando entender por que o Func permite chaves e a expressão não está permitindo. De qualquer forma, a expressão será compatível como Func. Existe alguma maneira de adicionar lógica de várias linhas à árvore de expressões? Se não, por que está restringindo isso?
Habeeb
8
@Habeeb: "De qualquer forma, a expressão será cumprida como Func" Nem sempre. Muitas vezes, nunca é compilado para um delegado - apenas examinado como dados. As árvores de expressão no .NET 4.0 ganharam a capacidade de incluir várias instruções via Expression.Block, mas a linguagem C # não suporta isso. Poderia, mas isso exigiria mais trabalho de design / implementação / teste.
precisa saber é o seguinte
26

Você pode colocar quantas linhas novas desejar em uma expressão lambda; C # ignora novas linhas.

Você provavelmente quis perguntar sobre várias declarações .

Várias instruções podem ser colocadas entre chaves.

Veja a documentação .

SLaks
fonte
17
Não seria mais preciso dizer que o C # trata todos os espaços em branco, incluindo novas linhas, igualmente? Parece um pouco enganador dizer que ignora as novas linhas - parece que as remove completamente e você pode dividir uma palavra-chave em uma nova linha ou algo assim.
Tesserex
6

Desde o C # 7:

Declaração de linha única:

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

Declaração multilinha:

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

embora sejam chamadas de funções locais, acho que isso parece um pouco mais limpo que o seguinte e é efetivamente o mesmo

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; };
Grande chefe
fonte
4
Func<string, bool> test = (name) => 
{
   if (name == "yes") return true;
   else return false;
}
Polity
fonte
5
Func <string, bool> test = name => name == "yes";
asawyer
3
O Polity está demonstrando o formato de várias linhas solicitado pela pergunta, não recebendo sugestões de golfe. Implementar seu código inteligente tornaria "não uma resposta"!
Caius Jard
3

Nas expressões Lambda (Guia de Programação em C #) :

O corpo de uma instrução lambda pode consistir em qualquer número de instruções; no entanto, na prática, normalmente não há mais que dois ou três.

jfs
fonte
0

Com o c # 7.0, você pode usar assim também

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
fonte
0

Digamos que você tenha uma aula:

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

Com o C # 7.0 dentro dessa classe, você pode fazer isso mesmo sem colchetes:

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

e

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

seria o mesmo que:

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

Isso também pode ser útil se você precisar escrever o método ou construtor regular em uma linha ou quando precisar de mais de uma instrução / expressão para ser compactada em uma expressão:

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

ou

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

ou

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

Mais sobre a desconstrução de tuplas na documentação .

Konard
fonte