再谈异常处理try catch finally

作者:至软 时间:2021-11-12 11:17:31 

 1. 查找系统中坏味道的异常处理代码

在上篇文章杂谈异常处理try-catch-finally中主要详细介绍了C#异常处理的概念,异常设计准则,基础知识等方面的内容,但对如何正确使用异常处理印象还不是特别深刻吧。在这篇中,我通过查找以前系统代码中存在坏味道的异常处理代码来分析和讲解如何正确使用异常处理。

1.1. 例一


/// <summary>
/// 保存记录
/// </summary>
/// <param name="entity">实体</param>
public virtual object Save(T entity)
{
ISession session = NHibernateUtils.GetCurrentSession();
ITransaction tx = null;
try
{
tx = session.BeginTransaction();
object id = session.Save(entity);
tx.Commit();
return id;
}
catch (HibernateException ex)
{
if (tx != null) tx.Rollback();
throw ex;
}
finally
{
NHibernateUtils.CloseSession();
}
}

上面代码中其中


catch (HibernateException ex)
{
if (tx != null) tx.Rollback();
throw ex;
}


代码在异常设计是不是与“如果了解特定异常在给定上下文中引发的条件,请考虑捕捉这些异常。”或“捕捉并再次引发异常时,首选使用空引发。这是保留异常调用堆栈的最佳方式。”的要求不太相符合呢?把throw ex;改成throw;或throw new RepositoryLayerException("保存记录发生错误!", ex);是不是符合上面两条异常设计准则了呢?


1.2. 例二


表示层代码




try
{
Cursor = Cursors.WaitCursor;
IApplicationContext ctx = ContextRegistry.GetContext();
IStoreRepository storeRepository = ctx.GetObject("StoreRepository") as IStoreRepository;
StoreInfo store = Store;
store.Name = XXName.Text.Trim();
storeRepository.Save(store);
}
catch (Exception ex)
{
ShowMessageBox(ex, MessageLevel.Error);
}
finally
{
Cursor = Cursors.Arrow;
}

领域层代码


private string _name;
/// <summary>
/// 店铺名称
/// </summary>
public virtual string Name
{
set
{
if (string.IsNullOrEmpty(value))
{
throw new ArgumentNullException("value", "店铺名称不能为空!");
}
if (ValidationUtils.GetLength(value,CharacterType.NVarChar) > 200)
{
throw new ArgumentOutOfRangeException("value", "店铺名称不能大于200!");
}
_name = value;
}
get { return _name; }
}

在这里需要说明一下,其中XXName是一个文本框控件,如果XXName文本框输入的值经常超过200个字符,会不停的弹出错误消息框,这样是不是会引起效率问题,涉及到效率问题我们会想到什么,对了就是Tester-Doer 模式,呵呵,在这里我们怎么应用这个模式呢?其实很简单,我们只要设置this.XXName.MaxLength = 200;是不是就解决了这个问题?

1.3. 思考总结

认真去分析,会发现在系统中坏味道的代码还真不少,原来在异常处理中自认为比较正确的做法,比较优美的做法发现都是存在问题的。经过这几天对异常处理的系统学习研究,对系统中不好做法的异常处理进行排查,还是学到了不少知识,也发现自己的不足,原来很多基础技术知识还可以更上一层楼。

标签:try,catch,finally
0
投稿

猜你喜欢

  • Elasticsearch查询及聚合类DSL语句宝典示例详解

    2023-01-10 18:51:46
  • Flutter开发技巧RadialGradient中radius计算详解

    2023-10-05 17:42:22
  • SpringBoot2.0 ZipKin示例代码

    2022-11-25 00:24:40
  • Java中List转Map List实现的几种姿势

    2022-10-23 19:19:57
  • c#读写excel文件使用示例

    2021-08-27 03:02:53
  • C#实现的文件操作封装类完整实例【删除,移动,复制,重命名】

    2022-09-14 20:41:14
  • springboot接口参数校验JSR303的实现

    2023-01-19 03:14:56
  • Android基于注解的6.0权限动态请求框架详解

    2023-08-13 13:31:32
  • 浅谈resultMap的用法及关联结果集映射

    2022-12-25 17:42:21
  • SpringBoot中@ComponentScan的使用详解

    2023-07-14 06:19:22
  • C#简单的加密类实例

    2022-12-15 11:31:18
  • 完整的医院就诊挂号系统基于Spring MVC + Spring + MyBatis实现

    2022-06-03 18:07:05
  • C#计算器编写代码

    2022-12-28 02:57:25
  • spring boot项目中MongoDB的使用方法

    2021-06-10 13:31:23
  • java ssm框架实现分页功能的示例代码(oracle)

    2021-10-31 01:14:40
  • Android使用自定义View实现360手机卫士波浪球进度的效果

    2023-03-21 19:18:34
  • SSH框架网上商城项目第21战之详解易宝支付的流程

    2021-11-11 17:06:38
  • C#实现快捷键的几种常用方法汇总

    2021-08-23 15:01:54
  • C#实现redis读写的方法

    2023-07-13 16:21:35
  • C#开发Windows UWP系列之布局面板RelativePanel

    2023-04-11 12:28:29
  • asp之家 软件编程 m.aspxhome.com