Action<T> 泛型委托:封装一个方法,该方法只采用一个参数并且不返回值。可以使用此委托以参数形式传递方法,而不用显式声明自定义的委托。该方法必须与此委托定义的方法签名相对应。也就是说,封装的方法必须具有一个通过值传递给它的参数,并且不能返回值。当然泛型委托不只是只能支持一个参数,它最多可以支持四个参数。  

  泛型委托与直接显示声明自定义委托的示例比较:

   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<T> 用法。比起自定义委托,明显可以看出代码简洁了。

public class TestAction1{   public static void Main()   {      Action<string> messageTarget;      messageTarget = ShowWindowsMessage;      messageTarget("Hello, World!");      }         private static void ShowWindowsMessage(string message)   {      MessageBox.Show(message);         }}

 Func<T, TResult> 委托:封装一个具有一个参数并返回 TResult 参数指定的类型值的方法。同理,这里的泛型委托只是接受一个参数的委托,它最多同样支持四个参数。TResult:此委托封装的方法的返回值类型。

  问题:目前本公司在写程序时,都使用了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>(TContract proxy, Action<TContract> 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, TReturn>(TContract proxy, Func<TContract, TReturn> func)        {            TReturn returnValue = 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<ISearchHotelForSquare, List<HotelGenericInfo>>(cli, proxy => proxy.GetHotelGenericListForSquare(requestInfo).ToList()); 

  说明:至于Invoke的应用,在System .Runtime .Remoting.Proxies有一个RealProxy,可以称做真正代理,里面有IMessage Invoke(System.Runtime.Remoting.Messaging.IMessage msg)方法:只不过这里面没有应用泛型委托。

        // 返回结果:
        //     The message returned by the invoked method, containing the return value and
        //     any out or ref parameters.
        public abstract IMessage Invoke(IMessage msg);

泛型委托在项目中的应用相关推荐

  1. 使用.NET中的Action及Func泛型委托

    原文 http://www.cnblogs.com/skm-blog/archive/2013/05/24/3096294.html 委托,在C#编程中占有极其重要的地位,委托可以将函数封装到委托对象 ...

  2. Unity 项目中委托Delegate用法案例

    Unity中Delegate的用法场景 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人! (拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar ...

  3. C语言中的函数指针、函数的直接/间接调用、C# 委托(自定义委托、内置泛型委托、委托的实例化、委托的一般使用(模板方法、回调方法)、泛型委托、多播委托、同步/异步使用委托)

    文章目录 C语言中的函数指针 函数的直接调用与间接调用 Java中没有与委托对应的功能实体 C# 委托 C# 自定义委托类型 C# 内置泛型委托类型 委托的实例化 委托也支持泛型的使用 委托的一般使用 ...

  4. C#中使用委托、接口、匿名方法、泛型委托实现加减乘除算法

    使用C#实现加减乘除算法经常被用作新手练习.本篇来分别体验通过委托.接口.匿名方法.泛型委托来实现. 使用委托实现 加减乘除拥有相同的参数个数.类型和返回类型,首先想到了使用委托实现. //创建一个委 ...

  5. 泛型委托Action和一些常见用法

    泛型委托Action Action的定义   在.Net2.0里面,Action只有一个定义 public delegate void Action(T arg); 定义一个普通的委托格式是: pub ...

  6. C#入门级——泛型、泛型类、泛型接口、泛型方法和泛型委托

    目录 一.泛型(generic) 二.为什么需要泛型类 类型膨胀 成员膨胀 使用object类 三.泛型的定义 定义泛型类 使用泛型类 泛型接口​​​​​​​ 两种泛型接口的实现方法 泛型方法 成员膨 ...

  7. 委托、lamda表达式..委托概念-匿名函数-泛型委托-Lamda表达式-多播委托

    委托 一.什么是委托? 将一个方法作为参数传递给另一个方法(参数类型为委托delegate).   声明一个委托类型. 委托所指向的函数必须跟委托具有相同的的签名(参数个数.参数类型.返回值一样). ...

  8. 七天学习计划_c#_[2][3][4][5]委托、事件、委托与事件的区别、泛型委托、Func\Action\predicate

    由于委托之前的博客已经详细写了,这里就简单的过一遍,复习一下: 了解委托 基于委托开发事件驱动程序变得非常简单. 使用委托可以大大简化多线程编程难度. 理解委托 委托也可以看做成一种数据类型,可以定义 ...

  9. 泛型委托 Predicate/Func/Action

    Predicate 泛型委托   表示定义一组条件并确定指定对象是否符合这些条件的方法.此委托由 Array 和 List 类的几种方法使用,用于在集合中搜索元素. 看看下面它的定义: // Summ ...

最新文章

  1. Django的Form表单
  2. [云炬创业管理笔记]第二章成为创业者讨论3
  3. IOS用CGContextRef画各种图形(文字、圆、直线、弧线、矩形、扇形、椭圆、三角形、圆角矩形、贝塞尔曲线、图片)...
  4. CentOS修改主机名(hostname)
  5. Android调试秘钥证书指纹获取方式
  6. [转载]oracle的表导入导出,表空间,用户名
  7. 如何配置java环境变量
  8. 14. 深入解析Pod对象(一)
  9. 190519每日一句
  10. 用FlyMcu和USB转TTL给stm32中烧录程序(stm32C8/C6)
  11. OpenCV曝光参数和快门时间的对应关系
  12. git rebase命令实际操作记录
  13. 做完电商直播后,怎么做直播复盘?
  14. 有AI就不搬砖?超乎你的想象!道翰天琼认知智能机器人平台API接口大脑为您揭秘-1。
  15. czl蒻蒟的OI之路2
  16. 数字电路基础知识——反相器的相关知识(噪声容限、VTC、转换时间、速度的影响因素、传播延时等)
  17. 尚硅谷-微信小程序文档
  18. 各个排序算法的时间复杂度、稳定性、快排的原理以及图解
  19. 医药领域知识图谱快速及医药问答项目--项目探究
  20. SDS之Object Storage: 对象存储,老树开新花

热门文章

  1. 【CVPR2020-谷歌】自动驾驶中多目标跟踪与检测框架 RetinaTrack
  2. SAP MIGO + 311将库存从IM管理库存地转入WM管理库存地,物料凭证号里不显示WM 选项卡
  3. 如何使用SAP零售系统中的LISTING?【中英文对照版】
  4. 2021年斯坦福AI指数报告重磅出炉!中国AI期刊影响力首超美国,视频处理是新风口
  5. 关于机器学习算法的16个技巧
  6. 关于深度学习推荐系统领域的15个问题
  7. 中美领军全球AI竞赛,人工智能被高估了么?
  8. 图解梯度下降背后的数学原理
  9. 放弃手工标记数据吧!斯坦福大学开源弱监督框架
  10. 机器学习-终结者是否会出现