C#委托基础及应用小结

 什么是委托?                                     

顾名思义,委托就是把事情给他人干,自己不干,别人帮忙干。参考市场经济下的委托工厂生产模式就明白了。如某驰名商标牛奶商自己不生产牛奶,但是旗下却有几款产品,这几款商品分别委托工厂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层。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章