#1,169 – Lambdas Supersede Anonymous Methods

Lambda expressions were introduced in C# 3.0 and supersede anonymous methods, which were introduced in C# 2.0.  There are some differences between lambda expressions and anonymous methods, but lambdas are now the preferred way to write inline code.

        static void Main(string[] args)
        {
            Dog d = new Dog("Bowser");

            // C# 1.0 - Named method
            d.Barked += d_Barked;

            // C# 2.0 - Anonymous method
            d.Barked += delegate (object sender,string e) {
                Console.WriteLine("My dog says {0}", e); };

            // C# 3.0 - Lambda expression
            d.Barked += (s, e) => Console.WriteLine("My dog says {0}", e); 

            d.Bark();

            Console.ReadLine();
        }

        static void d_Barked(object sender, string e)
        {
            Console.WriteLine("My dog says {0}", e);
        }

1169-001

#554 – Rules for Matching an Anonymous Method to a Delegate Type

When you declare an anonymous method and assign it to a delegate type or pass it as a delegate-typed parameter, the anonymous method is converted to an instance of the appropriate delegate.  There are several rules that you must follow so that this conversion can happen properly.

  • You can only omit the formal parameter list in the anonymous method declaration if
    • The delegate type’s parameter list has no ref or out parameters
    • The body of the anonymous method does not need to read or write any of the parameters
  • If you include the formal parameter list in the anonymous method declaration, you must include all of the parameters and the type must match for each parameter
  • Any object returned as the return value of the anonymous method must be able to be implicitly converted to the return type of the delegate

#553 – Anonymous Methods as Static or Instance Methods

An anonymous method that is declared within an instance method is considered itself to be an instance method of the class in which it was defined.  This means that it can make use of instance data within the class.

In the example below, an anonymous method is declared within the DogInteractions.BarkAtNeighbor method.  Since this is an instance method, the body of the anonymous method can make use of the numBarks instance variable.

    public class DogInteractions
    {
        private int numBarks = 0;

        public void BarkAtNeighbor(Dog d, string neighbor)
        {
            // Delegate passed into the Bark method,
            //   which will then invoke it.
            d.Bark(
                delegate(string barkSound)
                {
                    numBarks++;
                    Console.WriteLine("Bark #{0} - Hey {1}: {2}", numBarks, neighbor, barkSound);
                });
        }
    }

Similarly, if the anonymous method was declared within a static method, it would be considered itself to be static and could not make use of instance data within the class.

#550 – Anonymous Method Does Not Require Formal Parameters

An anonymous method declares the body of code to execute for a delegate inline with the declaration of the delegate instance.

In the example below, the delegate type takes a single string parameter and we include this parameter in our declaration of the anonymous method.

        private delegate void StringHandlerDelegate(string s);

        static void Main()
        {
            StringHandlerDelegate del1 =
                delegate (string s) { Console.WriteLine(s); };
            del1("Invoked via delegate");

The anonymous method expression shown above includes a list of format parameters, in this case a single string parameter. However, this list of parameters is optional, even if the delegate type includes one or more parameters. In the example below, we define a second anonymous method for the same delegate type, but without any formal parameters.

            StringHandlerDelegate del2 =
                delegate { Console.WriteLine("I'm ignoring my string parameter!"); };
            del2("Ignore me");

#549 – Anonymous Method Basics

Recall that an instance of a delegate is an object that refers to one or more methods.  Code that has access to the delegate  instance can execute the various methods via the delegate.

        private delegate void StringHandlerDelegate(string s);

        static void Main()
        {
            StringHandlerDelegate del1 = Method1;
            del1("Invoked via delegate");
        }

        static void Method1(string text)
        {
            Console.WriteLine(text);
        }

An anonymous method is a shorthand for declaring a delegate instance that allows declaring the code to execute as part of the delegate’s declaration, rather than in a separate method.

The code below is equivalent to the example above, but using an anonymous method, rather than a separately defined method.

        private delegate void StringHandlerDelegate(string s);

        static void Main()
        {
            StringHandlerDelegate del1 =
                delegate (string s) { Console.WriteLine(s); };
            del1("Invoked via delegate");
        }