写一段时间的程序,总是感觉开发过程中大部分的时间都花在了调试代码上,而不是实现功能。所以上网找了一下,如何尽早地发现Bug,提高软件质量的文章。看到了断言技术,感觉断言是每个程序员必备的基本功。可以让程序中的Bug在离其发生地最近的地方被断言发现,防止Bug的蔓延。
在.NET中的断言的使用,是使用System.Dig.Debug。断言一般是在程序处于Debug模式下,才起作用。而可以在程序发布时(即Release模式),编译器会采用条件编译,将断言从Release版本的dll中去掉。
该使用断言几种使用场景,如:
1、方法参数的合法性
2、对于非法情况进行断言而对于错误情况不断言且必须处理
3、对于任何假定进行断言
4、用断言对程序开发环境(OS/Compiler/Hardware )的假设进行检查
5、编写防错程序,然后在处理错误之后可用断言宣布发生错误(一般对于Switch语句中的default进行断言)
6、用断言保证没有定义的特性或功能不被使用(如果原先规定的一部分功能尚未实现,应进行断言)。
这些断言的使用场景,我都同意。不过,我有以下几个疑问:
1、对于第一条,由于断言会在程序的Release版本中由编译器自动去掉,那么往往我们开发一个基本库,public、protected修饰的方法怎么能保证调用者输入的参数的合法性呢(当然如果是调用者使用的是Debug版本的程序那是没有什么问题)。
2、我们将程序发布给用户,即使我们在开发过程中使用了断言,可以大大提高程序的质量,但是难免程序中仍然有Bug。那么用户在使用Release版本的程序时,如果程序出现Bug,我们怎么才能像调试阶段一样,在离Bug出生地最近的地方,发现它呢?我目前,只认为可以将程序出现的异常,在程序的最上层,捕获所有的异常,并将异常信息及堆栈信息作为日志保存下来。但是这个时候,我们还是难以定位这个Bug,因为其出生地已经难以定位了。
上面是我的一些疑问,还请各位指教讨论。对于什么时候该用断言,什么时候不应该用断言,还请各位也讨论一下。
在.NET中的断言的使用,是使用System.Dig.Debug。断言一般是在程序处于Debug模式下,才起作用。而可以在程序发布时(即Release模式),编译器会采用条件编译,将断言从Release版本的dll中去掉。
该使用断言几种使用场景,如:
1、方法参数的合法性
2、对于非法情况进行断言而对于错误情况不断言且必须处理
3、对于任何假定进行断言
4、用断言对程序开发环境(OS/Compiler/Hardware )的假设进行检查
5、编写防错程序,然后在处理错误之后可用断言宣布发生错误(一般对于Switch语句中的default进行断言)
6、用断言保证没有定义的特性或功能不被使用(如果原先规定的一部分功能尚未实现,应进行断言)。
这些断言的使用场景,我都同意。不过,我有以下几个疑问:
1、对于第一条,由于断言会在程序的Release版本中由编译器自动去掉,那么往往我们开发一个基本库,public、protected修饰的方法怎么能保证调用者输入的参数的合法性呢(当然如果是调用者使用的是Debug版本的程序那是没有什么问题)。
2、我们将程序发布给用户,即使我们在开发过程中使用了断言,可以大大提高程序的质量,但是难免程序中仍然有Bug。那么用户在使用Release版本的程序时,如果程序出现Bug,我们怎么才能像调试阶段一样,在离Bug出生地最近的地方,发现它呢?我目前,只认为可以将程序出现的异常,在程序的最上层,捕获所有的异常,并将异常信息及堆栈信息作为日志保存下来。但是这个时候,我们还是难以定位这个Bug,因为其出生地已经难以定位了。
上面是我的一些疑问,还请各位指教讨论。对于什么时候该用断言,什么时候不应该用断言,还请各位也讨论一下。
解决方案 »
- 请问:怎么看ibatisNet运行时的sql
- Oracle数据库 类型date怎么的当前日期--在线等
- 问一个IssueVision的问题
- 友情送分榜-穷人问题贴-最后一贴-by-lycoo
- 希望大家提供一个C#教程的FTP
- 用C#怎么样获取当前进程列表?
- 怎么通过用户控件中的控件改变缓存?
- PB中有:DateTime dt1; setNull(dt1) 定义一个DateTime变量,将其设为NULL值,在C#中对应的语句是什么?
- Adapter更新视图可以吗?
- 如何不用PANEL,只用PICTUREBOX 可以有滚动条来显示较大的图片?
- 如何调用这样的API
- .NET第三方控件NetAdvantage
http://blog.csdn.net/Knight94/archive/2006/06/18/809479.aspx
请问一下,你在编码中是如何使用Debug.Assert的
那是不是对每个断言的地方,用一个Log来替代呢?我对于什么时候该用Log,不是很有把握。有没有一个统一的解决方案呢?
我一般就在异常catch的时候放Log。或者重要操作的时候。
对于这一点还请各位指教
当然,希望你英语足够好。
那你使用的断言检查不会是Debug.Assert吧。因为如果用了Debug.Assert的话,当你以Release模式发布程序后,这些断言将不起作用。
“断言是一些只在调试版本才会被执行的函数或宏,他们会通过消息对话框提示哪些条件失败了。”也就是说,断言是以前C/C++开发中,没有异常这个概念,也没有像VS.net那样的高级开发环境中,程序员使用的一种调试辅助工具。即当项目比较大且多人开发时,断言在开发过程中就起到很大的作用了,在项目开发的几个过程,即添加新功能(新代码)时期,单个库测试时期,联合测试时期等,在这几种开发里程碑里,添加新功能时期尤其需要断言,它是当时唯一能够检测出内部的参数传递错误以及调用错误时进行必要的处理的功能。.Net中的断言同样不需要再Release时使用,因为贴主的问题是程序发布后进行参数检查,这时断言已经不需要了,因为检查客户输入是表示层代码的重要人物之一,否则.net也不会有WebForm/WinForm下的许多验证控件了。表示层的功能就是显示程序界面,接受用户的输入,进行验证,调用必要的代码进行处理并向用户提供反馈。我的意见是,只要是public/protected等公开的类方法,必须进行参数验证,验证失败抛出ArgumentException系列的异常。贴主如果要监视Release下客户端异常报告,那么只能用log文件,网上有很多(包括微软)这样的帮助库,可以去搜索并下载。
所以我想对于public/protected的对外公布的方法,我们难以甚至于没法保证,这些方法的输入参数的正确性,所以也符合异常的使用场景——有可能发生,无法控制的情况。所以得用抛出异常的方式来处理public/protected的输入参数的验证。这一点,我是很赞同TomMax(笑望人生) 的说法。
但是我也同样存在这样的疑问,如sp1234“如何证明断言可以在release时肯定都是多余的?”。的确,这种事情真的很难决定说,哪些断言应该去掉。
我想,如果Release版本的断言如果去掉,那么当程序出现了异常,即使我捕获了全局的unhandlerException异常,并用日志记录了异常信息及堆栈信息,但是由于没有断言,我仍然是很难根据异常信息来发现Bug,并解决它。
所以我就想,难道assert就真的如同sp1234(对 DLinq 架构颇为失望) 所说的,断言是c/c++的东西,在dotnet环境下编程,不应该用吗?我想存在就是合理,.net下为什么要有Debug.Assert这样的断言方法呢?
真的,我有点胡涂了。还请各位,多多讨论。可以不要局限于断言,大家可以谈谈,如果在开发阶段,如果减少bug,提高开发效率、提升开发质量。
而且assert只是简单地抛出异常,并没有条件编译,即不可以在Release中去掉。
不过,还请问你是怎么使用nunit中的assert中类的方法级内部进行断言的。我们一般都只是用nunit来对方法进行黑箱测试,即单元测试。
在永远不可能发生错误的地方使用断言。我的理解,比如说一个private方法中的string参数,传进来的时候不能为空。
在可能出错,程序应当处理的地方使用异常--我的理解,比如说调用一个远程服务器上的WebService,极有可能远程主机不可达,这时要用异常。