Anonymous Methods and Lambda Expressions

An anonymous function is an "inline" statement or expression that can be used wherever a delegate type is expected. You can use it to initialize a named delegate or pass it instead of a named delegate type as a method parameter.

You can use a lambda expression or an anonymous method to create an anonymous function. We recommend using lambda expressions as they provide more concise and expressive way to write inline code. Unlike anonymous methods, some types of lambda expressions can be converted to the expression tree types.

The Evolution of Delegates in C#

In C# 1.0, you created an instance of a delegate by explicitly initializing it with a method that was defined elsewhere in the code. C# 2.0 introduced the concept of anonymous methods as a way to write unnamed inline statement blocks that can be executed in a delegate invocation. C# 3.0 introduced lambda expressions, which are similar in concept to anonymous methods but more expressive and concise. These two features are known collectively as anonymous functions. In general, applications that target .NET Framework 3.5 or later should use lambda expressions.

The following example demonstrates the evolution of delegate creation from C# 1.0 to C# 3.0:

class Test
{
    delegate void TestDelegate(string s);
    static void M(string s)
    {
        Console.WriteLine(s);
    }

    static void Main(string[] args)
    {
        // Original delegate syntax required
        // initialization with a named method.
        TestDelegate testDelA = new TestDelegate(M);

        // C# 2.0: A delegate can be initialized with
        // inline code, called an "anonymous method." This
        // method takes a string as an input parameter.
        TestDelegate testDelB = delegate(string s) { Console.WriteLine(s); };

        // C# 3.0. A delegate can be initialized with
        // a lambda expression. The lambda also takes a string
        // as an input parameter (x). The type of x is inferred by the compiler.
        TestDelegate testDelC = (x) => { Console.WriteLine(x); };

        // Invoke the delegates.
        testDelA("Hello. My name is M and I write lines.");
        testDelB("That's nothing. I'm anonymous and ");
        testDelC("I'm a famous author.");

        // Keep console window open in debug mode.
        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }
}
/* Output:
    Hello. My name is M and I write lines.
    That's nothing. I'm anonymous and
    I'm a famous author.
    Press any key to exit.
 */

How to use lambda expressions in a query

You do not use lambda expressions directly in query syntax, but you do use them in method calls, and query expressions can contain method calls. In fact, some query operations can only be expressed in method syntax.

private static void TotalsByGradeLevel()
{
    // This query retrieves the total scores for First Year students, Second Years, and so on.
    // The outer Sum method uses a lambda in order to specify which numbers to add together.
    var categories =
    from student in students
    group student by student.Year into studentGroup
    select new { GradeLevel = studentGroup.Key, TotalScore = studentGroup.Sum(s => s.ExamScores.Sum()) };

    // Execute the query.
    foreach (var cat in categories)
    {
        Console.WriteLine("Key = {0} Sum = {1}", cat.GradeLevel, cat.TotalScore);
    }
}
/*
     Outputs:
     Key = SecondYear Sum = 1014
     Key = ThirdYear Sum = 964
     Key = FirstYear Sum = 1058
     Key = FourthYear Sum = 974
*/

Another example:

using System;

namespace Anonymous_Methods_and_Lambda_Expressions
{
    delegate void Operation(int number);
    class Program
    {
        static void Main(string[] args)
        {
            // This is an Anonymous way
            Operation op = delegate (int number)
            {
                Console.WriteLine($"{number} x 2 = {number * 2}");
            };
            op(2);

            // Generic delegates
            Action<int> operation = num => { Console.WriteLine($"{num} x 2 = {num * 2}"); };
            Func<int, int> myFunction = x => { return x * 2; };
            Func<int, string> anotherFunction = (x) => { Console.WriteLine($"{x}"); return "Hello"; };
            operation(2);

            Console.WriteLine(myFunction(6));

            // Final line
            Console.ReadLine();
        }

        static void Double(int number)
        {
            Console.WriteLine($"{number} x 2 = {number * 2}");
        }
    }
}

Last updated