当前位置: 首页 > 编程语言 > C# > 正文

C#3.0匿名方法的实现与应用

时间:2007-11-04 IT168 Yuanshu

前面的文章中,大家已经对C#3.0的新特性有了一个基本的了解,比如强大的LINQ语言和扩展方法的应用,今天给大家介绍的是C#3.0中添加的另一个重要的新特性:匿名方法。

1. 匿名溯源

匿名的历史可谓由来已久,在C#2.0中匿名方法就已经大量使用在委托(delegate)的应用场景中。下面我举几个例子大家可以简单回顾一下:

1) 当我们需要调用一个回调方法时,不需要构建委托对象,只需要将回调方法名传入,CLR会替我们完成委托对象的创建工作。

//example 1
public static void CallBackWithoutANewDelegateObject()
{
//这里QueueUserWorkItem方法需要一个委托作为参数,
//但我们仅仅传递给回调方法名,CLR可以自动为我们构造出委托对象的代码
ThreadPool.QueueUserWorkItem(SomeAsyncTask, 5);
}
private static void SomeAsyncTask(object o)
{
Console.WriteLine(o);
}

这个例子中我们没有构造出任何委托对象,而仅仅传递了回调方法名称,CLR帮我构建了创建委托对象的代码。

2)我们甚至不用显式定义回调方法,只需要使用delegate关键字内联的写出方法代码执行调用。

//example 2
public static void CallbackWithoutNewingADelegateObject()
{
//我们在这儿以内联形式写出回调方法体,而没有定义任何的回调方法
ThreadPool.QueueUserWorkItem(
delegate(object o) { Console.WriteLine(o); },
5);
}

这个例子中我们并没有定义上面的方法SomeAsyncTask,而是内联写出方法体。

3)我们甚至可以不写出调用方法的参数,CLR也会为我们生成正确的委托对象。

//example 3
this.BT_LOGIN.Click +=
delegate { MessageBox.Show("Button Login has been clicked!"); };

这是匿名方法最常见的使用场景,即在添加一个控件的事件处理函数时直接使用delegate写出方法代码而不需要另外定义方法函数。当我们的事件处理函数很简短时(比如上面的代码我们仅仅弹出一个对话框显示一条信息而已。)我们就可以使用这种方法,如果另外定义一个函数就会显得很累赘。而且方法的参数也可以省略(比如这里的Object sender, EventArgs e)

2. C#3.0中的匿名方法

1) 隐式类型变量 (Implicitly typed local variables)

var var1 = 1;
var var2 = 2;
var var3 = var1 + var2;
var var4 = "I'm a string.";

这里我们可以看到我们并没有指定变量的类型(int , string, …),但编译器会帮我们完成这一点。熟悉脚本语言的朋友们可能会对此次语法感到惊喜,但要注意的是,C#仍然是强类型的语言,所有类型都会在编译期确定,而不是像脚本那样等到运行时,下面这张图很清楚的说明了这一点: