什么是委托?
顾名思义,委托就是把事情给他人干,自己不干,别人帮忙干。参考市场经济下的委托工厂生产模式就明白了。如某驰名商标牛奶商自己不生产牛奶,但是旗下却有几款产品,这几款商品分别委托工厂A、B制造。代码可参考如下:
//定义委托(品牌方)
Delegate void mikeCompany(string type);
//声明回调函数(牛奶工厂A、B)
private void mikeA(string type)
{
//生产牛奶A...
}
private void mikeB(string type)
{
//生产牛奶B...
}
static void main(string[] args)
{
//触发回调,委托工厂A生产牛奶A
mikeCompany mkc = new mikeCompany(mikeA);
}
注意:委托和回调函数的签名需保持一致(如文中的 string type)
因为个人的使用的习惯,所以笔者想插入一下lambda,上面的代码使用lambda表达式将更简洁:
Delegate void mikeCompany(string type)
static void main(string[] agrs)
{
mikeCompany mkc = t =>
{
if(t == A)
{
productMikeA()..
}
}
}
以上就是用lambda表达式来简化委托的代码。想要了解lambda可以看本人上一篇转载的博文。
使用字典表和委托来简化switch语句
当你对委托了解越加深入后你会发现委托看起来跟switch很相似,确实是这样。二者都能实现分支实现,但是switch如果数量大的话维护起来将十分困扰,所以还是会选择前者来方便自己编码。以下是笔者优化自己一段代码。优化前代码:
[Route("GetMajorInfo_University")]
[LGApiAuthorize(ApiSecurity.Level2)]
[HttpGet]
public AjaxResult GetMajorInfoUniversity(string schoolID)
{
int Flag = 0;
List<CollegeStructUniversity> ret = bll.GetMajorInfoUniversity(schoolID, out Flag);
switch (Flag)
{
case 0: return new AjaxResult(AjaxResultStatus.Success, "请求成功", ret);
case 1: return new AjaxResult(AjaxResultStatus.ClientError, "参数错误", ret, -1);
case 10: return new AjaxResult(AjaxResultStatus.ServerError, "程序异常", ret, -2);
default: return new AjaxResult(AjaxResultStatus.Success, "请求成功", ret);
}
}
像这种控制器的返回接口很多都是相似的,几乎每个接口都会做参数检测、异常处理、请求成功等。所以一个接口一个switch...
代码一堆冗余,而且如果你要改变其中一条的内容,那么所有接口都要改显得有点笨了。
这个时候我们可以采用字典表加委托的方式将switch语句给独立出来,后面每个接口调用只需一行代码,十分简洁。性能上也要比switch好很多。字典表加委托的方式将switch语句给独立出来的代码如下:
delegate AjaxResult Func();
#region 采用字典表和委托代替switch
public AjaxResult returnValueHelper(int Ret, object obj)
{
Dictionary<int, Func> dic = new Dictionary<int, Func>();
dic[0] = new Func(Success);
dic[1] = new Func(ParamError);
dic[4] = new Func(NoPermission);
dic[5] = new Func(RepeatSubject);
dic[6] = new Func(RepeatCourse);
dic[10] = new Func(ServerError);
AjaxResult Success() { return new AjaxResult(AjaxResultStatus.Success, "请求成功", obj, 0); }
AjaxResult ParamError() { return new AjaxResult(AjaxResultStatus.ClientError, "参数错误", obj, -1); }
AjaxResult ServerError() { return new AjaxResult(AjaxResultStatus.ServerError, "程序异常,请联系管理员", obj, -2); }
AjaxResult NoPermission() { return new AjaxResult(AjaxResultStatus.ClientError, "权限不足", obj, -3); }
AjaxResult RepeatSubject() { return new AjaxResult(AjaxResultStatus.ClientError, "学科名称或编号重复,添加学科失败", obj, -4); }
AjaxResult RepeatCourse() { return new AjaxResult(AjaxResultStatus.ClientError, "课程名称或编号重复,添加课程失败", obj, -5); }
if (dic.ContainsKey(Ret)) return dic[Ret]();
else return dic[0]();
}
#endregion
如上代码,先定义委托 Func,再定义回调函数Success()等,最后再将回调函数写进字典表。如果传入参数 Ret在字典表中则返回对应的回调函数执行结果。是不是很方便。优化后的控制层接口代码如下:
#region 获取所有学院、专业信息
[Route("GetMajorInfo_University")]
[LGApiAuthorize(ApiSecurity.Level2)]
[HttpGet]
public AjaxResult GetMajorInfoUniversity(string schoolID)
{
int Flag = 0;
List<CollegeStructUniversity> ret = bll.GetMajorInfoUniversity(schoolID, out Flag);
return returnValueHelper(Flag, ret);
}
#endregion
在写接口的时候尽量不要把数据处理放在Controler层。