Un'espressione lambda C # può avere più di un'istruzione?


131

Un'espressione lambda C # può includere più di un'istruzione?

(Modifica: come indicato in molte delle risposte di seguito, questa domanda originariamente poneva domande su "righe" anziché "istruzioni".)


17
Sì, puoi usare più righe. Non mi sembra giusto renderlo una risposta completa.
Tesserex,

1
@Tesserex - cosa non lo rende una risposta ... hai ragione!
RQDQ

3
@RQDQ Poiché è una domanda sì o no, non mi sento degno del rappresentante che genererebbe dai voti.
Tesserex,

Risposte:


195

Sicuro:

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;
            }
        );

31

(Suppongo che tu stia davvero parlando di più dichiarazioni piuttosto che più righe.)

Puoi usare più istruzioni in un'espressione lambda usando le parentesi graffe, ma solo la sintassi che non usa le parentesi graffe può essere convertita in un albero di espressioni:

// 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; };

1
Sto cercando di capire perché Func consente le parentesi graffe e Expression non lo consente. Ad ogni modo Expression sarà rispettata come Func. Esiste un modo per aggiungere una logica a più righe all'albero delle espressioni? Se no, perché ci sono restrizioni?
Habeeb,

8
@Habeeb: "Ad ogni modo Expression rispetterà Func" Non sempre. Molte volte non viene mai compilato per niente da un delegato, appena esaminato come dati. Gli alberi delle espressioni in .NET 4.0 hanno ottenuto la possibilità di includere più istruzioni tramite Expression.Block, ma il linguaggio C # non lo supporta. Potrebbe, ma ciò richiederebbe più lavoro di progettazione / implementazione / test.
Jon Skeet,

26

Puoi inserire tutte le nuove righe che vuoi in un'espressione lambda; C # ignora le nuove righe.

Probabilmente intendevi chiedere più dichiarazioni .

Più istruzioni possono essere racchiuse tra parentesi graffe.

Vedere la documentazione di .


17
Non sarebbe più preciso dire che C # tratta tutti gli spazi bianchi, comprese le nuove linee, allo stesso modo? Sembra un po 'fuorviante dire che ignora le nuove righe - sembra che le elimini completamente e che tu possa dividere una parola chiave in una nuova riga o qualcosa del genere.
Tesserex,

6

Da C # 7:

Dichiarazione a riga singola:

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

Dichiarazione multilinea:

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

sebbene queste siano chiamate funzioni locali, penso che questo appaia un po 'più pulito del seguente ed è effettivamente lo stesso

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; };

4
Func<string, bool> test = (name) => 
{
   if (name == "yes") return true;
   else return false;
}

5
Func <string, bool> test = name => name == "yes";
asawyer,

3
Polity sta dimostrando il formato multilinea richiesto dalla domanda, non intrattenendo i suggerimenti sul golf. Implementare il tuo codice saggio lo renderebbe "non una risposta"!
Caius Jard,


0

Con c # 7.0 È possibile utilizzare anche in questo modo

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);
    }
}

0

Supponiamo che tu abbia una lezione:

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

Con il C # 7.0 all'interno di questa classe puoi farlo anche senza parentesi graffe:

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

e

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

sarebbe lo stesso di:

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

Questo potrebbe anche essere utile se devi scrivere un metodo o un costruttore regolare in una riga o quando hai bisogno di più di un'istruzione / espressione da impacchettare in una espressione:

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);

Maggiori informazioni sulla decostruzione delle tuple nella documentazione .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.