Methods in C#
(Page 1 of 4 )
In this third part of a ten-part series on C#, you will learn about lambda expressions, anonymous methods, and more. It is excerpted from chapter four of
C# 3.0 in a Nutshell, Third Edition, A Desktop Quick Reference, written by Joseph Albahari and Ben Albahari (O'Reilly; ISBN: 0596527578). Copyright © 2007 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.
Lambda Expressions (C# 3.0)
A lambda expression is an unnamed method written in place of a delegate instance. The compiler immediately converts the lambda expression to either:
- A delegate instance.
- An expression tree, of typeExpression<T>, representing the code inside the lambda expression in a traversable object model. This allows the lambda expression to be interpreted later at runtime (see the section “Building Query Expressions” in Chapter 8).
In the following example,squareis assigned the lambda expressionx=>x*x:
delegate int Transformer (int i);
class Test
{
static void Main()
{
Transformer square = x => x * x;
Console.WriteLine (square(3)); // 9
}
}
We could rewrite the example by converting the lambda expression into a method, and then call the method through the delegate. In fact, the compiler internally performs that translation for you when you assign a delegate a lambda expression:
delegate int Transformer (int i);
class Test
{
static void Main()
{
Transformer square = Square;
Console.WriteLine (square(3)); // 9
}
static int Square (int x) {return x * x;}
}
A lambda expression has the following BNF form:
(parameters) => expression-or-statement-block
For convenience, you can omit the parentheses if and only if there is exactly one parameter of an inferable type.
In our example, there is a single parameter,x, and the expression isx*x:
x => x * x;
Each parameter of the lambda expression corresponds to a delegate parameter, and the type of the expression (which may bevoid) corresponds to the return type of the delegate.
In our example,xcorresponds to parameteri, and the expressionx * xcorresponds to the return typeint, therefore being compatible with theTransformerdelegate:
delegate int Transformer (int i);
A lambda expression’s code can be a statement block instead of an expression. We can rewrite our example as follows:
x => {return x * x;};
Explicitly Specifying Lambda Parameter Types
The compiler can usually infer the type of lambda parameters contextually. When this is not the case, you must specify the type of each parameter explicitly. Consider the following delegate type:
delegate int Transformer (int i);
The compiler uses type inference to infer thatxis anint, by examiningTransfomer’s parameter type:
Transformer d = x => x * x;
We could explicitly specifyx’s type as follows:
Transformer d = (int x) => x * x;
Generic Lambda Expressions and the Func Delegates
With generic delegates, it becomes possible to write a small set of delegate types that are so general they can work for methods of any return type and any (reasonable) number of arguments. These delegates are the Func and Action delegates, defined in the System namespace:
delegate TResult Func <T> ();
delegate TResult Func
<T,TResult> (T1 arg1);
delegate TResult Func
<T1,T2,TResult> (T1 arg1, T2 arg2);
delegate TResult Func
<T1,T2,T3,TResult> (T1 arg1, T2 arg2, T3 arg3);
delegate TResult Func <T1,T2,T3,T4,TResult> (T1 arg1, T2 arg2, T3 arg3, T4 arg4);
delegate void Action ();
delegate void Action <T> (T1 arg1);
delegate void Action <T1,T2> (T1 arg1, T2 arg2);
delegate void Action <T1,T2,T3> (T1 arg1, T2 arg2, T3 arg3);
delegate void Action
<T1,T2,T3,T4> (T1 arg1, T2 arg2, T3 arg3,
T4 arg4);
These delegates are extremely general. TheTransformerdelegate in our previous example can be replaced with aFuncdelegate that takes a singleintargument and returns anintvalue:
These delegates are extremely general. The delegate in our previous example can be replaced with a delegate that takes a single argument and returns an value:
class Test
{
static void Main()
{
Func<int,int>square = x => x * x;
Console.WriteLine (square(3)); // 9
}
}
Next: Outer Variables >>
More C# Articles
More By O'Reilly Media
|
This article is excerpted from chapter four of C# 3.0 in a Nutshell, Third Edition, A Desktop Quick Reference, written by Joseph Albahari and Ben Albahari (O'Reilly; ISBN: 0596527578). Check it out today at your favorite bookstore. Buy this book now.
|
|