158

Can a C# lambda expression include more than one statement?

(Edit: As referenced in several of the answers below, this question originally asked about "lines" rather than "statements".)

Jon Schneider
  • 25,758
  • 23
  • 142
  • 170
paseena
  • 4,207
  • 6
  • 32
  • 51
  • 18
    Yes, you can use multiple lines. I don't feel right making it a full answer. – Tesserex Apr 13 '11 at 18:19
  • Good question. Yes, to have multiple statements after the arrow, you need to surround them with curly braces. – Yster Jun 19 '23 at 10:34

9 Answers9

229

Sure:

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;
            }
        );
Andrew
  • 18,680
  • 13
  • 103
  • 118
RQDQ
  • 15,461
  • 2
  • 32
  • 59
40

(I'm assuming you're really talking about multiple statements rather than multiple lines.)

You can use multiple statements in a lambda expression using braces, but only the syntax which doesn't use braces can be converted into an expression tree:

// 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
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    I am trying to understand why Func allow braces and Expression is not allowing. Anyway Expression will complied as Func, Is there any way to add multiple line logic to Expression Tree? If no, Why there are restricting that? – Habeeb Jan 03 '18 at 08:40
  • 9
    @Habeeb: "Anyway Expression will complied as Func" Not always. A lot of the time it's never compiled to a delegate at all - just examined as data. Expression trees in .NET 4.0 did gain the ability to include multiple statements via [Expression.Block](https://learn.microsoft.com/en-gb/dotnet/api/system.linq.expressions.expression.block?view=netstandard-1.6) but the C# *language* doesn't support that. It could, but that would require more design/implementation/test work. – Jon Skeet Jan 03 '18 at 08:43
31

You can put as many newlines as you want in a lambda expression; C# ignores newlines.

You probably meant to ask about multiple statements.

Multiple statements can be wrapped in braces.

See the documentation.

SLaks
  • 868,454
  • 176
  • 1,908
  • 1,964
  • 17
    Wouldn't it be more accurate to say C# treats all whitespace, including newlines, equally? It sounds a bit misleading to say it ignores newlines - it makes it seem like it just strips them out completely, and you could split a keyword across a newline or something. – Tesserex Apr 13 '11 at 18:41
7

Since C# 7:

Single line statement:

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

Multiline statement:

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

although these are called local functions I think this looks a bit cleaner than the following and is effectively the same

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
  • 1,413
  • 4
  • 24
  • 37
7
Func<string, bool> test = (name) => 
{
   if (name == "yes") return true;
   else return false;
}
Polity
  • 14,734
  • 2
  • 40
  • 40
  • 5
    Func test = name => name=="yes"; – asawyer Apr 13 '11 at 18:25
  • 5
    Polity is demonstrating the multi-line format requested by the question, not entertaining golfing suggestions. To implement your wise code would make it "not an answer"! – Caius Jard Nov 23 '17 at 14:54
3

From Lambda Expressions (C# Programming Guide):

The body of a statement lambda can consist of any number of statements; however, in practice there are typically no more than two or three.

user229044
  • 232,980
  • 40
  • 330
  • 338
jfs
  • 16,758
  • 13
  • 62
  • 88
1

Another Example.

var iListOfNumbers = new List<int>() { 1, 2, 3, 4, 5 };

Func<List<int>, int> arithmeticSum = iList =>
{
    var finalResult = 0;
            
    foreach (var i in iList)
        finalResult = finalResult + i;
            
    return finalResult;
};

Console.WriteLine(arithmeticSum.Invoke(iListOfNumbers));
Console.WriteLine(arithmeticSum(iListOfNumbers));
// The above two statements are exactly same.
VivekDev
  • 20,868
  • 27
  • 132
  • 202
0

With c# 7.0 You can use like this also

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);
    }
}
GWigWam
  • 2,013
  • 4
  • 28
  • 34
0

Let say you have a class:

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

With the C# 7.0 inside this class you can do it even without curly brackets:

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

and

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

would be the same as:

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

This also might be helpful if you need to write the a regular method or constructor in one line or when you need more then one statement/expression to be packed into one expression:

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

or

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

or

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

More about deconstruction of tuples in the documentation.

Konard
  • 2,298
  • 28
  • 21