We covered delegates in the previous chapter, as it was a pre-requisite for understanding anonymous methods and lambda expressions, the subject of the current chapter. By using an anonymous method, we can create a delegate instance with no need to have a separate method. By using the lambda expression, we can create a shorthand syntax for the anonymous method. In this chapter, we are going to dig up the anonymous methods as well as Lambda expressions. The topics in this chapter are as follows:
In the previous chapter, we already discussed how to declare a delegate using named methods. When using named methods, we've have to create a method first, give it a name, and then associate it with the delegate. To refresh our memory, a simple delegate declaration associated with a named method is provided as follows:
delegate void DelDelegate(int x); void DoSomething(int i) { /* Implementation */ } DelDelegate d = DoSomething;
From the preceding code, we simply create a delegate data type named DelDelegate
, and we also create a method named DoSomething
. After we have a named method, we can associate the delegate with the method. Fortunately, anonymous methods were announced in C# 2.0 to ease the use of delegates. They provide us with a shortcut to create a simple and short method that will be used once. The syntax to declare an anonymous method is as follows:
delegate([parameters]) { implementation }
The explanation for each element of the anonymous method syntax is as follows:
From the preceding syntax, we can see that an anonymous method is a method that doesn't have a name. We just need to define the arguments and the implementation of the method.
For further discussion, let's create a simple anonymous method, which we can find in the SimpleAnonymousMethods.csproj
project, as follows:
public partial class Program { static Func<string, string> displayMessageDelegate = delegate (string str) { return String.Format("Message: {0}", str); }; }
We now have an anonymous method we assign to the delegate displayMessageDelegate
delegate. We create the displayMessageDelegate
delegate using the Func
built-in delegate, which takes only one string argument and a return string value as well. If we need to run the anonymous method, we can invoke the delegate as follows:
public partial class Program { static void Main(string[] args) { Console.WriteLine( displayMessageDelegate( "A simple anonymous method sample.")); } }
After running the preceding code, we will get the following output on the console:
As we can see in the output console window, we have successfully invoked the anonymous method by calling the delegate name. Now, let's go back to the previous chapter to use some code from there and refactor it to an anonymous method. We are going to refactor the code of SimpleDelegates.csproj
, which we've discussed in the previous chapter. The following is the declaration of anonymous methods, and it can be found in the SimpleDelegatesRefactor.csproj
project:
public partial class Program { private static Func<int, int, int> AreaRectangleDelegate = delegate (int a, int b) { return a * b; }; private static Func<int, int, int> AreaSquareDelegate = delegate (int x, int y) { return x * y; }; }
We have two anonymous methods in our preceding code. We also use the Func
delegate, the built-in delegate we discussed in the previous chapter. To invoke the methods, we can invoke the delegate name as follows:
public partial class Program { static void Main(string[] args) { int i = AreaRectangleDelegate(1, 2); int j = AreaSquareDelegate(2, 3); Console.WriteLine("i = " + i); Console.WriteLine("j = " + j); } }
If we run the project, we will get an output like this:
Compared to the code in the SimpleDelegates.csproj
project, our code in the preceding SimpleDelegatesRefactor.csproj
project becomes simpler and shorter since we don't need to declare the delegate. The delegate is declared simultaneously with the creation of an anonymous method, such as the following code snippet:
private static Func<int, int, int> AreaRectangleDelegate = delegate (int a, int b) { return a * b; };
Here is the code we used in our previous chapter, named SimpleDelegates.csproj
:
public partial class Program { private delegate int AreaCalculatorDelegate(int x, int y); static int Square(int x, int y) { return x * y; } }
Using anonymous delegation , we have simplified our code compared to the code produced in the previous chapter.
We have now executed an anonymous method. However, the anonymous method can also be passed to a method as a parameter. Let's look at the following code, which we can find in the AnonymousMethodAsArgument.csproj
project:
public partial class Program { private static bool IsMultipleOfSeven(int i) { return i % 7 == 0; } }
First, we have a method named FindMultipleOfSeven
in this project. The method will be passed to the argument of the following method:
public partial class Program { private static int FindMultipleOfSeven(List<int> numList) { return numList.Find(IsMultipleOfSeven); } }
Then, we call the FindMultipleOfSeven()
method from the following method:
public partial class Program { private static void PrintResult() { Console.WriteLine( "The Multiple of 7 from the number list is {0}", FindMultipleOfSeven(numbers)); } }
We can also define the following List
variable to be passed to the FindMultipleOfSeven()
method argument:
public partial class Program { static List<int> numbers = new List<int>() { 54, 24, 91, 70, 72, 44, 61, 93, 73, 3, 56, 5, 38, 60, 29, 32, 86, 44, 34, 25, 22, 44, 66, 7, 9, 59, 70, 47, 55, 95, 6, 42 }; }
If we invoke the PrintResult()
method, we will get the following output:
The goal of the preceding program is to find a number that is multiplied by seven from the number list. And since 91
is the first number that meet this criteria, the FindMultipleOfSeven()
method returns that number.
Inside the FindMultipleOfSeven()
method, we can find the Find()
method passing the IsMultipleOfSeven()
method as an argument, as shown in the following code snippet:
return numList.Find(IsMultipleOfSeven);
We can, if we want, replace this method with the anonymous method, as follows:
public partial class Program { private static int FindMultipleOfSevenLambda( List<int> numList) { return numList.Find( delegate(int i) { return i % 7 == 0; } ); } }
We now have the FindMultipleOfSevenLambda()
method, which invokes the Find()
method and passes the anonymous method to the method argument. Since we have passed the anonymous method, we don't need the FindMultipleOfSeven()
method any longer. We can invoke the FindMultipleOfSevenLambda()
method using the PrintResultLambda()
method, as follows:
public partial class Program { private static void PrintResultLambda() { Console.WriteLine( "({0}) The Multiple of 7 from the number list is {1}", "Lambda", FindMultipleOfSevenLambda(numbers)); } }
We will get the following output we after we have executed the PrintResultLambda()
method:
As we can see from the output window, we still retrieve 91
as a result of a number multiplication of 7
. However, we have successfully passed the anonymous method as the method argument.
When writing anonymous methods, here are some things that we should keep in mind:
delegate (int a, int b) { return a * b; };
private static Func<int, int, int> AreaRectangleDelegate = delegate (int a, int b) { return a * b; };
public partial class Program { private static void Conflict() { for (int i = 0; i < numbers.Count; i++) { Action<int> actDelegate = delegate(int i) { Console.WriteLine("{0}", i); }; actDelegate(i); } } }
Here are some advantages of using anonymous methods: