什麼是委託?
顧名思義,委託就是把事情給他人幹,自己不幹,別人幫忙幹。參考市場經濟下的委託工廠生產模式就明白了。如某馳名商標牛奶商自己不生產牛奶,但是旗下卻有幾款產品,這幾款商品分別委託工廠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層。