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層。

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