C#扩展方法应用之 try catch finally 封装

本文将介绍如何利用扩展方法将 try catch finally 语句块简化成如下的调用形式:

        public void Test1()
        {
            Employee emp = new Employee();

            emp.Try(p => p.Work())
                .Catch(e => HandleException(e))
                .Finally(p => p.Rest());
        }

虽然这样做似乎节省不了太多代码,但看起来更工整一点。下面介绍如何实现:

一. try

     public class TryUnit<T> where T : class
        {
            public TryUnit(T obj, Action<T> action)
            {
                this.Obj = obj;
                this.Action = action;
            }
            public T Obj { get; private set; }
            public Action<T> Action { get; private set; }
        }

     public static TryUnit<T> Try<T>(this T obj, Action<T> action) where T : class
        {
            return new TryUnit<T>(obj, action);
        }

首先定义一个TryUnit泛型类,用来存储try的调用对象和想调用的方法,然后为对象扩展一个Try方法,返回一个TryUnit对象。

二. catch

     public class CatchUnit<T> where T : class
        {
            public CatchUnit(TryUnit<T> tryUnit, Action<Exception> exAction)
            {
                this.Obj = tryUnit.Obj;
                this.Action = tryUnit.Action;
                this.ExAction = exAction;
            }
            public T Obj { get; private set; }
            public Action<T> Action { get; private set; }
            public Action<Exception> ExAction { get; private set; }
        }

     public static CatchUnit<T> Catch<T>(this TryUnit<T> tryUnit, Action<Exception> exAction) where T : class
        {
            return new CatchUnit<T>(tryUnit, exAction);
        }

与try的做法类似,再定义一个CatchUnit类,它比TryUnit多出一个对异常处理的Action;然后为TryUnit对象扩展一个Catch方法,返回一个CatchUnit对象。也就是说,在对象调用了Try方法返回TryUnit之后,才可以继续调用Catch方法,必须按顺序调用。Try和Catch实际上都是在传递参数,方法的执行将会延迟到Finally中。

三. finally

     public static void Finally<T>(this TryUnit<T> tryUnit) where T : class
        {
            try
            {
                tryUnit.Action(tryUnit.Obj);
            }
            finally
            {

            }
        }

        public static void Finally<T>(this CatchUnit<T> catchUnit) where T : class
        {
            try
            {
                catchUnit.Action(catchUnit.Obj);
            }
            catch (Exception e)
            {
                catchUnit.ExAction(e);
            }
            finally
            {

            }
        }

        public static void Finally<T>(this TryUnit<T> tryUnit, Action<T> action) where T : class
        {
            try
            {
                tryUnit.Action(tryUnit.Obj);
            }
            finally
            {
                action(tryUnit.Obj);
            }
        }

        public static void Finally<T>(this CatchUnit<T> catchUnit, Action<T> action) where T : class
        {
            try
            {
                catchUnit.Action(catchUnit.Obj);
            }
            catch (Exception e)
            {
                catchUnit.ExAction(e);
            }
            finally
            {
                action(catchUnit.Obj);
            }
        }

Finally方法根据是否包括异常处理块,finally块中是否执行操作可派生出4个重载版本。完整的 try catch finally 组合方法是对CatchUnit的扩展方法,在调用Catch方法返回CatchUnit对象时调用;如果没有异常处理块,则直接从try方法的返回类型TryUnit上扩展出只有 try finally 的组合方法。即使finally块中不做任何处理,也需要调用Finally方法,因为所有处理都被延迟到了Finally中调用。

好了,代码就介绍到这里,这是本人在博客园的第一篇文章,有写的不好的地方望大家原谅,并欢迎提出意见,O(∩_∩)O谢谢。

时间: 2024-10-27 18:32:54

C#扩展方法应用之 try catch finally 封装的相关文章

C#中的反射和扩展方法的运用

前段时间做了一个练手的小项目,名叫Book_Bar,用来卖书的,采用的是三层架构,也就是Models,IDAL,DAL,BLL 和 Web , 在DAL层中各个类中有一个方法比较常用,那就是 RowToClass ,顾名思义,也就是将 DataTable 中的数据封装到 Models 中.结果导致在DAL各个类中写了很多类似的方法,后来就直接把它抽取出来做成了 DataTable和 DataRow的扩展方法, 下面是代码: using System; using System.Collectio

泛型List集合转化为DateTable的扩展方法

文章出处:http://www.codeproject.com/Tips/867866/Extension-Method-for-Generic-List-Collection-to-Da 这段代码是能够帮助你把泛型集合List转出成DataTable的扩展方法. 背景: 不知道你是否知道这个扩展方法,但是你可以不做任何修改的去使用下面这个类的代码. 使用代码:   using System; using System.Collections.Generic; using System.Comp

扩展方法对json序列化及反序列化

this+类型名+变量名,.NET 3.0 之后新增的一种特性,叫"扩展方法". int类型变量都能调用toString()方法,将int类型变量转换成string型变量:如果需要更改转换的形式,比如将int类型变量转换成指定格式的字符串,并且这种方法调用非常频繁,可以编写扩展方法.扩展方法能够向现有类型"添加"方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型.扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用. 例如下列代码: n

ASP.Net string 类的扩展方法 [转]

string 类的扩展方法列表(基本相同于 IEnumerable<T> 接口的成员列表): Aggregate<>     //累加 All<>        //是否都满足条件 Any<>        //是否有一个满足条件 AsEnumerable<>  // AsParallel<>    // AsQueryable<>    // Average<>      //平均值 Cast<>

【开源】OSharp框架解说系列(3):扩展方法

〇.前言 扩展方法使你能够向现有类型“添加”方法,而无需创建新的派生类型.重新编译或以其他方式修改原始类型. 扩展方法是一种特殊的静态方法,但可以像扩展类型上的实例方法一样进行调用. 对于用 C# 和 Visual Basic 编写的客户端代码,调用扩展方法与调用在类型中实际定义的方法之间没有明显的差异. 最常见的扩展方法是 LINQ 标准查询运算符,它将查询功能添加到现有的 System.Collections.IEnumerable 和 System.Collections.Generic.

WinForm TextBox 扩展方法数据验证

本文转载:http://www.cnblogs.com/gis-crazy/archive/2013/03/17/2964132.html 查看公司项目代码时,存在这样一个问题:winform界面上有很多信息填写,提交后台服务器更新,但数据的合法验证及值的转换却不太敢恭维,一堆的if判断和转换,便想着是否能扩展个方法出来,琢磨出个思路,记录下来与大家共同探讨,有不对的地方还请大家指正. 设计思路: 1. 由于大部分从TextBox控件中获取数据值,可以扩展个泛型方法出来,直接根据转换后的数据类型

WinForm TextBox自定义扩展方法数据验证

本文转载:http://www.cnblogs.com/gis-crazy/archive/2013/03/17/2964132.html 查看公司项目代码时,存在这样一个问题:winform界面上有很多信息填写,提交后台服务器更新,但数据的合法验证及值的转换却不太敢恭维,一堆的if判断和转换,便想着是否能扩展个方法出来,琢磨出个思路,记录下来与大家共同探讨,有不对的地方还请大家指正. 设计思路: 1. 由于大部分从TextBox控件中获取数据值,可以扩展个泛型方法出来,直接根据转换后的数据类型

LinQ 定义扩展方法3.1

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Reflection; using System.Diagnostics; namespace ExtensionMethodDump { class Program { static void Main(string[] args) { var song = new { Artist = "Juss

Linq扩展方法获取单个元素

在使用Linq 提供的扩展方法时,First(OrDefault), Single(OrDefault), Last(OrDefault)都具有返回单个元素的功能.MSDN对这些方法的描述只有功能说明,没有关于内部的相关实现的描述说明. 首先我们来看下MSDN上关于这些扩展方法的官方描述: First: 返回序列中的第一个元素 . FirstOrDefault: 返回序列中的第一个元素:如果未找到元素,则返回默认值. Last:返回序列的最后一个元素. LastOrDefault: 返回序列中的