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».)

paseena
la source
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;
            }
        );
RQDQ
la source
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; };
Jon Skeet
la source
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 .

SLaks
la source
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; };
BigChief
la source
4
Func<string, bool> test = (name) => 
{
   if (name == "yes") return true;
   else return false;
}
Régime politique
la source
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
3

À partir d' expressions Lambda (Guide de programmation C #) :

Le corps d'une instruction lambda peut être constitué de n'importe quel nombre d'instructions; cependant, en pratique, il n'y en a généralement pas plus de deux ou trois.

jfs
la source
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);
    }
}
jigar prajapati
la source
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 .

Konard
la source