4

Can I follow any simple synax or rules for building "lambda expression" in C#? I read some articles and understood what a lambda expression is, but if I have the general syntax or rules that would be helpful.

2 Answers 2

10

There are multiple ways of expressing lambdas, depending on the exact scenario - some examples:

    // simplest form; no types, no brackets
    Func<int, int> f1 = x => 2 * x;
    // optional exlicit argument brackets
    Func<int, int> f2 = (x) => 2 * x;
    // optional type specification when used with brackets
    Func<int, int> f3 = (int x) => 2 * x;
    // multiple arguments require brackets (types optional)
    Func<int, int, int> f4 = (x, y) => x * y;
    // multiple argument with explicit types
    Func<int, int, int> f5 = (int x, int y) => x * y;

The signature of the lambda must match the signature of the delegate used (whether it is explicit, like above, or implied by the context in things like .Select(cust => cust.Name)

You can use lambdas without arguments by using an empty expression list:

    // no arguments
    Func<int> f0 = () => 12;

Ideally, the expression on the right hand side is exactly that; a single expression. The compiler can convert this to either a delegate or an Expression tree:

    // expression tree
    Expression<Func<int, int, int>> f6 = (x, y) => x * y;

However; you can also use statement blocks, but this is then only usable as a delegate:

    // braces for a statement body
    Func<int, int, int> f7 = (x, y) => {
        int z = x * y;
        Console.WriteLine(z);
        return z;
    };

Note that even though the .NET 4.0 Expression trees support statement bodies, the C# 4.0 compiler doesn't do this for you, so you are still limited to simple Expression trees unless you do it "the hard way"; see my article on InfoQ for more information.

Sign up to request clarification or add additional context in comments.

Comments

8

A lambda expression is, fundamentally, a shorthand notation for a function pointer. More commonly, a lambda expression is the propagation of input data into an expression that computes a result. In most cases, you will use lambda expressions in their more common form:

int[] numbers = new[] { 1, 3, 11, 21, 9, 23, 7, 4, 18, 7, 7, 3, 21 };

var twentyoneCount = numbers.Where(n => n == 21).Count();
var sumOfgreaterThanSeven = numbers.Sum(n => n > 7 ? n : 0);

In their less common form, lambda expression can replace more cumbersome delegate forms:

myButton.Click += new EventHandler(myButton_Click);
// ...
void myButton_Click(object sender, EventArgs e)
{
    // TODO: Implement button click handler here
}

Or the less common, and less verbose:

myButton.Click += delegate(object sender, EventArgs e)
{
    // TODO: Implement button click handler here
};

The following lambda expression achieves the same result as the above two:

myButton.Click += (s,e) =>
{
    // TODO: Implement button click handler here
};

The power of this latter form really comes from its capability to create closures. A closure is where you implement a function within a function, and "close" around parameters and variables from the parent function scope:

private void DoSomething(IList<string> input, SomeObject source)
{
    source.OnSomeEvent += (s,e) => return input.Sum();
}

5 Comments

Excellent .It exactly took me the real programming world. Thousand thanks to jrista
"A lambda expression is, fundamentally, a shorthand notation for a function pointer." Not necessarily. An important distinction and a crucial feature of lambdas is the ability to treat them as data (expression trees) rather than code (anonymous methods). stackoverflow.com/questions/793571/…
@Mehrdad: True, lambdas do initially become expression trees. However, the end result of evaluating an expression tree is evaluating a dynamic method, pointed to by a delegate. The expression tree is just the intermediate representation of the ultimate function pointer. Note the .Compile() method, which returns a delegate: msdn.microsoft.com/en-us/library/bb345362.aspx
jrista: But no-one forces you to call .Compile() on an expression tree. The canonical example is LINQ to SQL. It doesn't call compile on your expression tree and the end result is not a function. It's a generated SQL statement.
Mehrdad: Good point. In cases like L2S, you are absolutely right, they behave as expression trees in their entirety.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.