DotNet 3.0+ 新特性学习 之 匿名方法&Lambda表达式(Anonymous Method&Lambda Expression)
参考 : 不能不说的C#特性-匿名方法和Lambda表达式 (横刀天笑)
我的C# 3.0之新特性学习笔记(2) (Jimmypony)
嘻嘻,两位没意见吧?
定义:
匿名方法 : 顾名思义,就是没有方法名的方法。
Lambda 表达式,其实就是匿名方法的另一种形式,其格式为 :参数列表 => 表达式/语句块。
理解:
1) 何为参数列表。此参数列表跟一个普通的函数的参数列表时一样的。
2) 何时用匿名方法和Lambda表达式
A. 需要一个临时方法,该方法只是用一次或者使用很少几次。
B. 方法体很短,以至于声明也很短。
实现:
铛铛铛铛,各位看官,这次我们来讲的是匿名方法和Lambda表达式。不是很难,写出来的代码也很优雅。首先,我们来看没有匿名方法的时代。
Case Scenario: 当一个事件被触发的时候,进行数据绑定。
我们有一个DataBind() 方法,如下
static void DataBind() { // To do
Console.WriteLine("DataBinding"); } |
我们有一个叫RefreshButton的类,它有一个属性是 Name, 当它的Name改变的时候,会触发NameChanged事件。来看下面代码
class RefreshButton { public event EventHandler NameChanged;
protected virtual void OnNameChanged(EventArgs e) { if (NameChanged != null) { NameChanged(this, e); } }
string name;
public string Name { get { return name; } set { if (name != value) { name = value; OnNameChanged(new EventArgs()); } } } } |
好了,我们要在main方法里给NameChanged事件加一个方法
Dot Net 2.0 时代
static void Main(string[] args) { RefreshButton btnRefresh = new RefreshButton();
// In 2.0 btnRefresh.NameChanged += new EventHandler(btnRefresh_NameChanged);
btnRefresh.Name = "Refresh";
Console.ReadKey(); }
static void btnRefresh_NameChanged(object sender, EventArgs e) { DataBind(); } |
在2.0时代,我们要自己定义一个方法,在给它加上,无形中增加了很多敲代码的时间。当然,VS2005/2008有智能感知能力,但是从代码可读性来看,也不是非常满意。当读到” btnRefresh_NameChanged” 方法时,你可能还需要看看它的具体实现,来回跳来跳去很麻烦。
Dot Net 3.0时代
static void Main(string[] args) { RefreshButton btnRefresh = new RefreshButton();
// In 2.0 //btnRefresh.NameChanged += new EventHandler(btnRefresh_NameChanged);
// In 3.0 btnRefresh.NameChanged += delegate(Object sender, EventArgs e) { DataBind(); };
btnRefresh.Name = "Refresh";
Console.ReadKey(); } |
OK 了,看少了什么?“static void btnRefresh_NameChanged(object sender, EventArgs e)” 这个方法没有了。直接在上面了。“btnRefresh.NameChanged += delegate(Object sender, EventArgs e){ DataBind(); };” 这样代码量少了,同时,思路也看的清晰了。
在看Lambda表达式怎么写这个
static void Main(string[] args) { RefreshButton btnRefresh = new RefreshButton();
// Lambda Express btnRefresh.NameChanged += (sender, e) => { DataBind(); };
btnRefresh.Name = "Refresh";
Console.ReadKey(); } |
又少了些东东吧?参数列表(sender, e)=> 表达式(DataBind()),Lamda表达式的标准结构。
其实匿名方法跟Lambda表达式都是一样的,只不过写的方式不同罢了。可以用Ildasm看一下就知道了,他们都会转化成一个“AnonymousMethod.Program::'CS$<>9__CachedAnonymousMethodDelegate1'”。
只不过Lambda表达式比匿名方法有更好的可读性。
下面重点说一下Lambda表达式的写法:
- 当输入参数为空时,左边的括号是不能省略的,比如
() => Console.WriteLine("This is a null parameters lambda expression"); |
- 当语句为一条的时候,可以不用加大括号,比如
(a,b) => Console.WriteLine("This is a null parameters lambda expression"); |
- 带返回值得,如输入a, b,返回a+b这类的,比如
(a, b) => {return a + b}; |
- 多个表达式用{}来括起来。比如
btnRefresh.NameChanged += (sender, e) => { if (e != null) Console.WriteLine(e.ToString());
DataBind(); }; |
注意事项(都是个人观点哟):
1. 当表达式较短的时候,且该方法很少再被别的方法或者类调用的时候,才使用。如果表达式很长,那么用Lambda反而给人很邋遢的感觉。
2. 匿名方法和lambda表达式一般只用于替换委托方法的。单独定义方法的时候,这个是不可用的。
呼~~~又写好一篇。呵呵,这些都是为了下一个比较NB的feature做准备,它是谁呢?且听下回分解。。。