本文将介绍如何利用扩展方法将 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谢谢。