欢迎光临

木子屋

标题: 好的编程习惯收益的是自己

作者: dnawo

日期: 2010-11-26 00:12 AM

分类: 网络文摘

内容: 前两天帮QQ群中的一个同学远程解决一个问题，这个同学据说自己折腾了一天都没搞定，给他结果以后感想非常多，今天有时间把这个问题以及背后隐藏的问题分享给大家。
下面说的吃异常的错误不仅初学者会犯，很多工作很多年的人也经常会犯这种错误，因此虽然在很多人看起来很简单，我还是在这里罗嗦了，希望对有的人有帮助。
这位同学说他写的程序总是报错说字段ParentId没找到，但是数据库中是有代码的。他是通过SQLHelper获得一个DataTable，然后把DataTable展示到ListView中进行数据展示的。示例性代码如下：
复制内容到剪贴板 程序代码DataSet ds = SQLHelper.ExecuteDataSet("select * from T_Persons");
listview1.DataSource = ds;
listview1.FilterExpression = "ParentId=3";
其实他的这个程序是有很大缺陷的，因为他是在UI层中进行数据过滤的，这个问题暂且不提。
主要问题是，T_Persons表中是有ParentId这个字段的，但是总是报异常"没有ParentId字段"。
一直让他很费解，因此我就猜测程序中有被吃掉的异常，因此我在VisualStudio中打开异常检测，打开主菜单→调试→异常，将Common Language Runtime Exception勾选上，这样就表示对于捕获的异常也Break，这样就可以发现被吃掉的异常了。
程序运行，果然在SQLHelper.ExecuteDataSet调用SqlConnection环节中看到异常抛出了，是"数据库连接失败"，示例性代码如下：
复制内容到剪贴板 程序代码DataSet ds = new DataSet();
try
{
SqlConnection conn = new SqlConnection(.........);
//...
adapter.Fill(ds);
}
catch
{
}
return ds;
原来是他的连接字符串写错了。由于他想"耳根子清净"，就可耻的把异常给吃掉了，这样虽然数据库根本就没连接上，ExecuteDataSet方法仍然好像啥事都没发生一样假模假样的返回一个空的DataSet，由于这个DataSet什么表结构都没有，最后报异常"没有ParentId字段"也就不足为奇。
异常就是一种程序中没有预料到的问题，既然属于没有预料到的，就不应该不想看异常就把所有异常catch吃掉，本来ExecuteDataSet执行数据库操作已经失败了，后续的代码也就没有意义了，不应该继续执行了，应该让用户或者开发人员知道"这里出错了"，而不是继续掩耳盗铃的执行下去，否则很容易造成程序进入一个逻辑混乱的状态，出现各种奇怪的问题。
异常也就是意外，是没有预料到的情况，既然是意外，一般情况不需要开发人员去处理。异常了就异常了，没什么大不了的，异常了反而容易发现程序中的错误。对于有的情况确实需要catch异常的地方，只要不是处理后重新抛出，也最好将异常通过Log4Net等日志工具记录下来，方便开发人员排查问题。
有人说程序一旦出现异常多难看呀?"客户看到一堆异常的英文界面就发怒，还是吃了好呀"，其实不要吃异常和不让用户看到"一堆异常的英文界面"并不冲突，比如在ASP.Net中就可以通过定制错误页的方式来解决，将错误页显示的模式设置为"RemoteOnly"，这样普通用户看的是定制后的没有"一堆异常的英文界面"的页面，而对于开发人员和系统管理员看到的则还是异常页面，"两不耽误"！
"不要吃异常"、"不要使用魔法数"、"资源最好用using进行管理"等这些非常常见的好的编程习惯是最容易被初学者忽略的，最终不遵守好习惯而自食其果的例子也屡见不鲜，建议大家要认真遵守这些基本的原则，最终受益的仍然是自己。

+ 查看当前日志评论 (0)

登录

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 1.598 ms

返回

标题: 好的编程习惯收益的是自己

你没有权限发表评论

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 1.598 ms

返回

暂无评论

返回

────────────

木子屋

PJBlog3 v3.2.9.518 Inside.

Processed In 1.645 ms

返回