C#2.0介绍了一个新特性--匿名方法,允许开发者在线(inline)声明自己的函数代码而无须使用委托函数(delegate function)。C#3.0中提供了一个新特性--Lambda表达式,它提供了完成相同目标的更加简洁的格式。让我们在讨论Lambda表达式以前 仔细研究一下匿名方法。
匿名方法
假设你需要创建一个按钮,当点击它的时候更新ListBox里的内容。在C#1.0和1.1里,你要这样做:
在C#2.0里,你需要这样做:
就像你看到的一样,你不必要特别的声明一个新方法来将它连接到一个事件上。你可以在C#2.0里使用匿名方法来完成同样的工作。C#3.0里介绍了一种更 加简单的格式,Lambda表达式,你可以直接使用"=>"来书写你的表达式列表,后面跟上一个表达式或者语句块。
Lambda表达式中的参数
Lambda表达式中的参数可以是显式或者隐式类型的。在一个显式类型参数列表里,每个表达式的类型是显式指定的。在一个隐式类型参数列表里,类型是通过上下文推断出来的:
Lambda演算实例
下面的例子给出了两种不同的方法来打印出一个list中长度为偶数的字符串。第一种方法AnonMethod使用了匿名方法,第二种LambdaExample则是通过Lambda演算实现:
匿名方法
假设你需要创建一个按钮,当点击它的时候更新ListBox里的内容。在C#1.0和1.1里,你要这样做:
- public MyForm()
- {
- listBox = new ListBox(...);
- textBox = new TextBox(...);
- addButton = new Button(...);
- addButton.Click += new EventHandler(AddClick);
- }
- void AddClick(object sender, EventArgs e)
- {
- listBox.Items.Add(textBox.Text);
- }
- public MyForm()
- {
- listBox = new ListBox(...);
- textBox = new TextBox(...);
- addButton = new Button(...);
- addButton.Click += delegate
- {
- listBox.Items.Add(textBox.Text);
- };
Lambda表达式中的参数
Lambda表达式中的参数可以是显式或者隐式类型的。在一个显式类型参数列表里,每个表达式的类型是显式指定的。在一个隐式类型参数列表里,类型是通过上下文推断出来的:
- (int x) => x + 1 // 显式类型参数
- (y,z) => return y * z; // 隐式类型参数
下面的例子给出了两种不同的方法来打印出一个list中长度为偶数的字符串。第一种方法AnonMethod使用了匿名方法,第二种LambdaExample则是通过Lambda演算实现:
- // Program.cs
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.Query;
- using System.Xml.XLinq;
- using System.Data.DLinq;
- namespace LambdaExample
- {
- public delegate bool KeyValueFilter<K, V>(K key, V value);
- static class Program
- {
- static void Main(string[] args)
- {
- List<string> list = new List<string>();
- list.Add("AA");
- list.Add("ABC");
- list.Add("DEFG");
- list.Add("XYZ");
- Console.WriteLine("Through Anonymous method");
- AnonMethod(list);
- Console.WriteLine("Through Lambda expression");
- LambdaExample(list);
- Dictionary<string, int> varClothes= new Dictionary<string,int>();
- varClothes.Add("Jeans", 20);
- varClothes.Add("Shirts", 15);
- varClothes.Add("Pajamas", 9);
- varClothes.Add("Shoes", 9);
- var ClothesListShortage = varClothes.FilterBy((string name,
- int count) => name == "Shoes" && count < 10);
- // example of multiple parameters
- if(ClothesListShortage.Count > 0)
- Console.WriteLine("We are short of shoes");
- Console.ReadLine();
- }
- static void AnonMethod(List<string> list)
- {
- List<string> evenNumbers = list.FindAll(delegate(string i)
- { return (i.Length % 2) == 0; });
- foreach (string evenNumber in evenNumbers)
- {
- Console.WriteLine(evenNumber);
- }
- }
- static void LambdaExample(List<string> list)
- {
- var evenNumbers = list.FindAll(i =>(i.Length % 2) == 0); // example of single parameter
- foreach(string i in evenNumbers)
- {
- Console.WriteLine(i);
- }
- }
- }
- public static class Extensions
- {
- public static Dictionary<K, V> FilterBy<K, V>
- (this Dictionary<K, V> items, KeyValueFilter<K, V> filter)
- {
- var result = new Dictionary<K, V>();
- foreach(KeyValuePair<K, V> element in items)
- {
- if (filter(element.Key, element.Value))
- result.Add(element.Key, element.Value);
- }
- return result;
- }
- }
- }