可以使用匿名函数来初始化命名委托,或传递命名委托(而不是命名委托类型)作为方法参数。
共有两种匿名函数,以下主题中分别讨论了这些函数:
-
Lambda 表达式(C# 编程指南) .
通常,针对 .NET Framework 版本 3.5 及更高版本的应用程序应使用 Lambda 表达式。
例演示了从 C# 1.0 到 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. */
Lambda 表达式用于编写 LINQ 查询表达式特别有用。
如下面的示例所示,可以将此表达式传递给委托类型:
delegate int del(int i); static void Main(string[] args) { del myDelegate = x => x * x; int j = myDelegate(5); //j = 25 }
创建表达式树类型:
using System.Linq.Expressions; namespace ConsoleApplication1 { class Program { static void Main(string[] args) { Expression<del> myET = x => x * x; } } }
Lambda 表达式返回表达式的结果,并采用以下基本形式:
两个或更多输入参数由括在括号中的逗号分隔:
(x, y) => x == y
如果出现这种情况,您可以按以下示例中所示方式显式指定类型:
(int x, string s) => s.Length > x
使用空括号指定零个输入参数:
() => SomeMethod()
方法在 .NET 公共语言运行时上下文的外部将没有意义。
Lambda 语句的主体可以包含任意数量的语句;但是,实际上通常不会多于两个或三个语句。
delegate void TestDelegate(string s); … TestDelegate myDel = n => { string s = n + " " + "World"; Console.WriteLine(s); }; myDel("Hello");
带有标准查询运算符的lambda
例如,假设有以下委托类型:
public delegate TResult Func<TArg0, TResult>(TArg0 arg0)
在调用下面的 Func 委托时,该委托将返回 true 或 false 以指示输入参数是否等于 5:
Func<int, bool> myFunc = x => x == 5; bool result = myFunc(4); // returns false of course
如果指定 Expression<Func> 参数,Lambda 将编译为表达式树。
Count 方法:
int[] numbers = { 5, 4, 1, 3, 9, 8, 6, 7, 2, 0 }; int oddNumbers = numbers.Count(n => n % 2 == 1);
n) 的数量,这些整数除以 2 时余数为 1。
numbers 数组包含所有元素都为 left 9 的一个序列,因为这是在不满足条件的第一个数字:
var firstNumbersLessThan6 = numbers.TakeWhile(n => n < 6);
>=) 混淆。
var firstSmallNumbers = numbers.TakeWhile((n, index) => n >= index);
lambda中的推理类型:
在编写 Lambda 时,通常不必为输入参数指定类型,因为编译器可以根据 Lambda 主体、基础委托类型以及 C# 语言规范中描述的其他因素推断类型。如下例子:
customers.Where(c => c.City == "London");