asp.net ashx處理程式中switch case的替代方案總結
阿新 • • 發佈:2019-08-02
目錄
- 1、用委託字典代替switch...case;
- 2、利用反射替代switch...case;
- 3、比較兩種方案
- 4、其他方案
- 5、說明
- 6、參考
在開發 asp.net 專案中,通常使用一般處理程式(ashx)處理前端傳送過來的請求,因為一個handler會處理多個請求,故ajax請求中一般都會加一個action的引數,在handler里根據這個action做相應的處理或返回相應的資料,這裡大多數人都會想到用switch...case做判斷,一開始我也是用的switch,但漸漸地發現,每個case不像一個程式碼塊,不能為其中的變數提供一個獨立的作用域!而且,如果case的情況比較多的話,程式碼看上去也比較臃腫難維護;
1、用委託字典代替switch...case;
首先在handler裡宣告一個私有的靜態委託字典,key為action字串,value為Func
完整示例程式碼:
namespace WebApplication1 { public class Handler1 : IHttpHandler { static Dictionary<string, Action<HttpContext>> MapActions = new Dictionary<string, Action<HttpContext>>(StringComparer.OrdinalIgnoreCase) { {"Add", Add}, {"Sub", Sub} }; public void ProcessRequest(HttpContext context) { context.Response.ContentType = "text/plain"; try { var action = context.Request["Action"]; if (string.IsNullOrEmpty(action)) { context.Response.StatusCode = (int) HttpStatusCode.BadRequest; } if (MapActions.ContainsKey(action)) { var actionFun = MapActions[action]; if (actionFun != null) { actionFun(context); //或 //actionFun.Invoke(context); } else { context.Response.StatusCode = (int) HttpStatusCode.NotImplemented; } } else { context.Response.StatusCode = (int) HttpStatusCode.NotFound; } } catch (Exception e) { context.Response.StatusCode = (int) HttpStatusCode.InternalServerError; } finally { context.Response.End(); } } public static void Add(HttpContext context) { int num1 = int.Parse(context.Request["Num1"]); int num2 = int.Parse(context.Request["Num2"]); int result = num1 + num2; context.Response.Write(result); } public static void Sub(HttpContext context) { int num1 = int.Parse(context.Request["Num1"]); int num2 = int.Parse(context.Request["Num2"]); int result = num1 - num2; context.Response.Write(result); } public bool IsReusable { get { return false; } } } }
2、利用反射替代switch...case;
利用反射,將action的值與具體的方法對應上;
完整示例程式碼:
namespace WebApplication1 { public class Handler2 : IHttpHandler { static readonly Type[] SearchParamType = new[] { typeof(HttpContext) }; public void ProcessRequest(HttpContext context) { var result = ActionInvoke(context); context.Response.ContentType = "text/plain"; context.Response.Write(result); } private object ActionInvoke(HttpContext ctx) { var actionFun = this.GetType().GetMethod("ProcessAction_" + ctx.Request["action"] ?? "", BindingFlags.NonPublic | BindingFlags.IgnoreCase | BindingFlags.Instance | BindingFlags.Public, null, SearchParamType, null); if (null == actionFun) { return "UnknowAction"; } return actionFun.Invoke(this, new[] { ctx }); } public int ProcessAction_Add(HttpContext context) { int num1 = int.Parse(context.Request["Num1"]); int num2 = int.Parse(context.Request["Num2"]); int result = num1 + num2; return result; } public int ProcessAction_Sub(HttpContext context) { int num1 = int.Parse(context.Request["Num1"]); int num2 = int.Parse(context.Request["Num2"]); int result = num1 - num2; return result; } public bool IsReusable { get { return false; } } } }
3、比較兩種方案
反射會造成一定的效能損耗;所以使用委託字典方案更加靠譜;
4、其他方案
可以使用設計模式實現,比如工廠模式,狀態模式,中介模式等,但用在上述這個場景,那麼就有殺雞用牛刀的 感覺了;
5、說明
在簡單的邏輯中,case分支少,很少擴充套件,那麼應該用switch語句,因為簡單明瞭,易於閱讀。
如果在複雜的邏輯中,複雜而且混亂的case,而且經常擴充套件什麼的,就應該用委託和反射,使用快取機制。
6、參考
重構:switch語句改成策略模式還是狀態模式:https://blog.csdn.net/qq_21381465/article/details/51298808
中介模式: https://www.cnblogs.com/insus/p/4134383.html