代码重构之没有理由拒绝Lambda表达式
Lambda表示是在C# 3.0推出的新特性,而匿名方法是C# 2.0推出的新特性,这一切都是为了让代码变得更简洁,更容易理解。
最近开始做一些Silverlight的应用项目,发现在Silverlight和后台代码交互时大量使用的是异步回调的方式;而异步处理特别是需要有返回结果,比如调用webService返回数据,哪怕是一个普通的Event事件处理,通常情况下都要写不少代码,定义委托类型,回调方法等。
如果熟练的开发人员对.net framework每个版本有所了解一定会使用Lambda表示来简化这些代码。
下面就简单的说明一下如何使用Lambda表达式来重构你的代码
Button.Click事件开始
通常的写法(C# 1.0)
this.button.Click +=new EventHandler(button_Click);
void button_Click(object sender, EventArgs e)
{
throw new NotImplementedException();
}
以上代码在C# 2.0(匿名方法)可以重构成
this.button.Click +=delegate{
throw new NotImplementedException();
};
//或者
this.button.Click +=delegate(object obj, EventArgs args){
throw new NotImplementedException();
};
使用Lambda表达式重构
//Lamdba
this.button.Click += (s, ev) => { throw new NotImplementedException(); };
从中我们可以看出Lambda表达式可以让你的代码更加简洁,可读性更好。
通过上面的例子应该很容易可以发现很多事件,委托都可以用Lambda表达式重构
Func<int, int > max = delegate(int a, int b)
{
if (a > b)
{
return a;
}
else
{
return b;
}
};
等价于
Func<int, int> max = (a, b) =>
{
if (a > b)
{
return a;
}
else
{
return b;
}
};
Lambda表达式语法
(参数列表)=〉表达式或语句块
"=〉"推导符号
WCF Client异步回调如何重构
通常的写法如下
ServiceClient webService = new ContactServiceClient("binaryBinding");
webService.GetContactByLastNameCompleted += new EventHandler< GetContactByLastNameCompletedEventArgs>(webService_GetContactByLastNameCompleted);
webService.GetContactByLastNameAsync(this.lastNameTextBox.Text);
this.act.IsActive = true;
void webService_GetAddressCompleted(object sender, BusinessApp.ContactServiceReference.GetAddressCompletedEventArgs e)
{
//this.addGrid.ItemsSource = e.Result;
}
Lambda表达重构如下
ServiceClient webService = new ContactServiceClient("binaryBinding");
webService.GetContactByLastNameCompleted += (s,e)=>{
//this.addGrid.ItemsSource = e.Result;
};
webService.GetContactByLastNameAsync(this.lastNameTextBox.Text);
从上面看代码非常的简洁
下面用更加专业的手法再重构一下
这次重构的目的是为了让这段代码更好被其他人使用我们把他封装一下
public void GetServiceData(Action<IEnumerable<Contact>,Exception> callback,string inputtext)
{
var webService = new ContactServiceClient("binaryBinding");
webService.GetContactByLastNameCompleted += (s, e) =>
{
var usercallback = e.UserState as Action<IEnumerable<Contact>, Exception>;
if (usercallback == null)
return;
if (e.Error != null)
{
usercallback(null, e.Error);
return;
}
usercallback(e.Result, null);
};
webService.GetContactByLastNameAsync(inputtext,callback);
}
调用上面的方法
GetServiceData((contactList, error) =>
{
if (error != null)
MessageBox.Show(error.Message);
else
this.addGrid.ItemsSource = contactList;
}
);
RIA DomainContext Lambda写法
#region query callback
/*
var db2=new DbDomainContext() db2.Load(db2.GetByPKQuery(this.TradeCode,this.CopEmsNo,this.CopImgNo),
loadOperation =>
{
loadOperation.Completed += (s, e) =>
{
var e1= loadOperation.Entities;
if (e1.Count() > 0)
{
Console.WriteLine(e1.First());
}
};
}, null);
*/
#endregion
#region query.completed
var query = db2.Load(db2.GetByPKQuery(this.TradeCode, this.CopEmsNo, this.CopImgNo));
query.Completed +=(s,e)=>
{
PRE_EMS3_ORG_EXG item = null;
LoadOperation<PRE_EMS3_ORG_EXG> q = (LoadOperation<PRE_EMS3_ORG_EXG>)s;
if (q.Entities.Count() > 0)
{
item = q.Entities.First();
}
};
#endregion
没有理由拒绝Lambda表达式
既可以提高可读性,又能够减少代码数量,我实在找不出任何理由拒绝Lambda表达式