泛型委托使用
泛型委托基础
class Program
class Program { // 泛型委托,与普通委托类似,不同之处只在于使用泛型委托要指定泛型参数 public delegate T MyGenericDelegate(T obj1,T obj2); int AddInt(int x, int y) { return x + y; }string AddString(string s1, string s2) { return s1 + s2; }static void Main(string[] args) { Program p = new Program(); MyGenericDelegate intDel; intDel = p.AddInt; Console.WriteLine("int代理的值是{0}", intDel(100, 200)); MyGenericDelegate stringDel; stringDel = p.AddString; Console.WriteLine("string代理的值是{0}", stringDel("aaa", "bbb")); } }
为了方便开发,.NET基类库针对在实际开发中最常用的情形提供了几个预定义好的委托,这些预定义委托用得很广,比如在编写lambda表达式和开发并行计算程序时经常要用到他们。
.NET提供的泛型委托包括action和func
感悟:对泛型委托基本属于有点认识,但从来没真正在项目中使用过,有时感觉没有合适的场景应用,但看了artech兄的文章,我才明白,原来泛型委托真的可以做很多事情,而且效果往往是没有使用委托所达不到的。
【泛型委托使用】Action
泛型委托与直接显示声明自定义委托的示例比较:
1:显示声明自定义委托:
delegate void DisplayMessage(string message); public class TestCustomDelegate { public static void Main() { DisplayMessage messageTarget; messageTarget = ShowWindowsMessage; messageTarget("Hello, World!"); } private static void ShowWindowsMessage(string message) { MessageBox.Show(message); } }
2: Action
public class TestAction1 { public static void Main() { ActionmessageTarget; messageTarget = ShowWindowsMessage; messageTarget("Hello, World!"); } private static void ShowWindowsMessage(string message) { MessageBox.Show(message); } }
Func
问题:目前本公司在写程序时,都使用了log4net,我想大家在做异常时,都会利用try catch来捕获异常,日志就在catch块中完成,但每个方法都写一堆的try catch往往显的有点别扭。虽然写程序时提倡尽量去捕获具体的错误异常,但总会有你预想不到的异常抛出,为此直接捕获Exception算是不错的做法。
具体场景:在客户端调用WCF服务时,我们都需要在客户做异常处理,最常见的错误异常为CommunicationException,TimeoutException,Exception示例如下:
try { //执行方法调用 ...... (proxy as ICommunicationObject).Close(); } catch (CommunicationException ex) { (proxy as ICommunicationObject).Abort(); WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据异常CommunicationException:" + ex.ToString()); } catch (TimeoutException ex) { (proxy as ICommunicationObject).Abort(); WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据超时TimeoutException:" + ex.ToString()); } catch (Exception ex) { (proxy as ICommunicationObject).Close(); WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据异常Exception:" + ex.ToString()); }
但如果这种代码遍布整个项目,我想就有重构的必要了,因为项目中最好不要出现类似复制的代码出现,为此我们可以采用Invoke形式来重构我们已有代码,下面给出两个方法,一个是没有返回值的,一个是有值的。
public static void Invoke(TContract proxy, Action action) { try { action(proxy); (proxy as ICommunicationObject).Close(); } catch (CommunicationException ex) { (proxy as ICommunicationObject).Abort(); WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据异常CommunicationException:" + ex.ToString()); } catch (TimeoutException ex) { (proxy as ICommunicationObject).Abort(); WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据超时TimeoutException:" + ex.ToString()); } catch (Exception ex) { (proxy as ICommunicationObject).Close(); WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据异常Exception:" + ex.ToString()); } } public static TReturn Invoke (TContract proxy, Func func) { TReturn returnValue = https://www.it610.com/article/default(TReturn); try { returnValue = func(proxy); } catch (CommunicationException ex) { (proxy as ICommunicationObject).Abort(); WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据异常CommunicationException:" + ex.ToString()); } catch (TimeoutException ex) { (proxy as ICommunicationObject).Abort(); WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据超时TimeoutException:" + ex.ToString()); } catch (Exception ex) { WebLog.SquareLog.CommonLogger.Error("取积分广场首页酒店数据异常Exception:" + ex.ToString()); } return returnValue; }
如何调用:可以看出客户端代码已经变成一条简洁代码了,它即完成了完整的异常处理,而且也把所有能够捕获的异常信息记录下来。
list = ErrorHandler.Invoke(cli, proxy => proxy.GetHotelGenericListForSquare(requestInfo).ToList());
--此文章根据网络资源整理.纯属个人笔记,别无其它商业用途.
转载于:https://www.cnblogs.com/cby-love/p/5516544.html
推荐阅读
- 由浅入深理解AOP
- 【译】20个更有效地使用谷歌搜索的技巧
- mybatisplus如何在xml的连表查询中使用queryWrapper
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- MybatisPlus使用queryWrapper如何实现复杂查询
- iOS中的Block
- Linux下面如何查看tomcat已经使用多少线程
- 使用composer自动加载类文件
- android|android studio中ndk的使用
- 使用协程爬取网页,计算网页数据大小