Une expression lambda C # peut-elle avoir plus d'une instruction?


131

Une expression lambda C # peut-elle inclure plusieurs instructions?

(Modifier: comme indiqué dans plusieurs des réponses ci-dessous, cette question portait à l'origine sur les «lignes» plutôt que sur les «déclarations».)


17
Oui, vous pouvez utiliser plusieurs lignes. Je ne me sens pas bien d'en faire une réponse complète.
Tesserex

1
@Tesserex - de quoi ne pas en faire une réponse ... vous avez raison!
RQDQ

3
@RQDQ Parce que c'est une question oui ou non, je n'ai pas l'impression que cela mérite le représentant que cela générerait à partir des votes positifs.
Tesserex

Réponses:


195

Sûr:

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

(Je suppose que vous parlez vraiment de plusieurs déclarations plutôt que de plusieurs lignes.)

Vous pouvez utiliser plusieurs instructions dans une expression lambda en utilisant des accolades, mais seule la syntaxe qui n'utilise pas d'accolades peut être convertie en une arborescence d'expression:

// 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
J'essaie de comprendre pourquoi Func autorise les accolades et Expression ne le permet pas. Quoi qu'il en soit, l'expression sera conforme en tant que Func, existe-t-il un moyen d'ajouter une logique à plusieurs lignes à l'arborescence d'expression? Si non, pourquoi y a-t-il des restrictions?
Habeeb

8
@Habeeb: "De toute façon, l'expression sera conforme en tant que Func" Pas toujours. La plupart du temps, il n'est jamais compilé pour un délégué - il est simplement examiné en tant que données. Arbres d'expression dans .NET 4.0 ont gagner la possibilité d'inclure plusieurs déclarations via Expression.Block mais le C # langue ne supporte pas. Cela pourrait, mais cela nécessiterait plus de travail de conception / mise en œuvre / test.
Jon Skeet

26

Vous pouvez mettre autant de nouvelles lignes que vous le souhaitez dans une expression lambda; C # ignore les nouvelles lignes.

Vous vouliez probablement poser des questions sur plusieurs déclarations .

Plusieurs instructions peuvent être entourées d'accolades.

Consultez la documentation .


17
Ne serait-il pas plus précis de dire que C # traite tous les espaces, y compris les nouvelles lignes, de la même manière? Cela semble un peu trompeur de dire qu'il ignore les nouvelles lignes - cela donne l'impression que cela les supprime complètement et vous pouvez diviser un mot-clé sur une nouvelle ligne ou quelque chose du genre.
Tesserex

6

Depuis C # 7:

Déclaration sur une seule ligne:

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

Déclaration multiligne:

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

bien que ce soient des fonctions locales, je pense que cela semble un peu plus propre que les suivants et est effectivement le même

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";
avocat

3
Polity démontre le format multiligne demandé par la question, et non des suggestions de golf divertissantes. Implémenter votre code sage en ferait "pas une réponse"!
Caius Jard


0

Avec c # 7.0, vous pouvez également utiliser comme ça

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

Disons que vous avez une classe:

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

Avec le C # 7.0 à l'intérieur de cette classe, vous pouvez le faire même sans accolades:

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

et

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

serait le même que:

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

Cela peut également être utile si vous devez écrire une méthode régulière ou un constructeur sur une ligne ou lorsque vous avez besoin de plusieurs instructions / expressions à regrouper dans une seule expression:

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

Plus d'informations sur la déconstruction des tuples dans la documentation .

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.