Delegates, Lamdba Expressions and Anonymous Methods: Declare, Instantiate, and Use A Delegate
Delegates, Lamdba Expressions and Anonymous Methods: Declare, Instantiate, and Use A Delegate
// Declare a delegate.
C# 2.0 provides a simpler way to write the previous declaration, as shown in the following example.
In C# 2.0 and later, it is also possible to use an anonymous method to declare and initialize a delegate, as
shown in the following example.
In C# 3.0 and later, delegates can also be declared and instantiated by using a lambda expression, as
shown in the following example.
1
using System;
// Define a custom delegate that has a string parameter and returns void.
class TestClass
// method Hello.
hiDel = Hello;
// method Goodbye.
byeDel = Goodbye;
// form multiDel.
2
Console.WriteLine("Invoking delegate hiDel:");
hiDel("A");
byeDel("B");
multiDel("C");
multiMinusHiDel("D");
/* Output:
Hello, A!
Goodbye, B!
Hello, C!
Goodbye, C!
Goodbye, D!
*/
Parameters
arg1
Type: T1
3
The first parameter of the method that this delegate encapsulates.
arg2
Type: T2
Type Parameters
in T1
The type of the first parameter of the method that this delegate encapsulates.
in T2
The type of the second parameter of the method that this delegate encapsulates.
You can use the Action<T1, T2> delegate to pass a method as a parameter without explicitly declaring a
custom delegate. The encapsulated method must correspond to the method signature that is defined by
this delegate. This means that the encapsulated method must have two parameters that are both
passed to it by value, and it must not return a value
using System;
using System.IO;
ConcatStrings concat;
if (Environment.GetCommandLineArgs().Length > 1)
concat = WriteToFile;
else
concat = WriteToConsole;
concat(message1, message2);
4
private static void WriteToFile(string string1, string string2)
try
catch
finally
The following example simplifies this code by instantiating the Action<T1, T2> delegate instead of
explicitly defining a new delegate and assigning a named method to it.
using System;
using System.IO;
if (Environment.GetCommandLineArgs().Length > 1)
concat = WriteToFile;
else
concat = WriteToConsole;
concat(message1, message2);
}
5
private static void WriteToConsole(string string1, string string2)
{
Console.WriteLine("{0}\n{1}", string1, string2);
}
You can use this delegate to represent a method that can be passed as a parameter without explicitly
declaring a custom delegate. The encapsulated method must correspond to the method signature that is
defined by this delegate. This means that the encapsulated method must have two parameters, each of
which is passed to it by value, and that it must return a value.
For example, the following code explicitly declares a delegate named ExtractMethod and assigns a
reference to the ExtractWords method to its delegate instance.
using System;
6
foreach (string word in extractMeth(title, 5))
Console.WriteLine(word);
if (limit > 0)
else
return phrase.Split(delimiters);
The following example simplifies this code by instantiating a Func<T1, T2, TResult> delegate instead of
explicitly defining a new delegate and assigning a named method to it.
using System;
7
Anonymous Methods
In versions of C# before 2.0, the only way to declare a delegate was to use named methods. C# 2.0
introduced anonymous methods and in C# 3.0 and later, lambda expressions supersede anonymous
methods as the preferred way to write inline code. However, the information about anonymous
methods in this topic also applies to lambda expressions.
// Create a delegate.
// Declare a delegate.
class TestClass
Printer p = delegate(string j)
{ System.Console.WriteLine(j);
};
p = new Printer(TestClass.DoWork);
8
static void DoWork(string k)
System.Console.WriteLine(k);
/* Output:
*/
Lambda Expressions
A lambda expression is an anonymous function that you can use to create delegates or expression tree
types. By using lambda expressions, you can write local functions that can be passed as arguments or
returned as the value of function calls. Lambda expressions are particularly helpful for writing LINQ
query expressions
To create a lambda expression, you specify input parameters (if any) on the left side of the lambda
operator =>, and you put the expression or statement block on the other side. For example, the lambda
expression x => x * x specifies a parameter thats named x and returns the value of x squared. You can
assign this expression to a delegate type, as the following example shows:
delegate int del(int i);
static void Main(string[] args)
{
del myDelegate = x => x * x;
int j = myDelegate(5); //j = 25
}
Expression Lambdas
A lambda expression with an expression on the right side of the => operator is called an expression
lambda. Expression lambdas are used extensively in the construction of Expression Trees (C# and Visual
Basic). An expression lambda returns the result of the expression and takes the following basic form:
The parentheses are optional only if the lambda has one input parameter; otherwise they are required.
Two or more input parameters are separated by commas enclosed in parentheses:
(x, y) => x == y
Sometimes it is difficult or impossible for the compiler to infer the input types. When this occurs, you
can specify the types explicitly as shown in the following example:
9
(int x, string s) => s.Length > x
() => SomeMethod()
Note in the previous example that the body of an expression lambda can consist of a method call.
However, if you are creating expression trees that are evaluated outside of the .NET Framework, such as
in SQL Server, you should not use method calls in lambda expressions. The methods will have no
meaning outside the context of the .NET common language runtime.
Statement Lambdas
A statement lambda resembles an expression lambda except that the statement(s) is enclosed in braces :
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.
myDel("Hello");
Statement lambdas, like anonymous methods, cannot be used to create expression trees.
10