到目前为止,我已经做了一年的专业软件工程师,并获得了计算机科学学位。我知道c++和C中的断言有一段时间了,但直到最近才知道它们存在于c#和。net中。
我们的生产代码不包含任何断言,我的问题是这个…
我应该开始在我们的生产代码中使用断言吗?如果可以,什么时候使用它最合适?这样做会更有意义吗
Debug.Assert(val != null, "message");
or
if ( val == null )
throw new exception("message");
到目前为止,我已经做了一年的专业软件工程师,并获得了计算机科学学位。我知道c++和C中的断言有一段时间了,但直到最近才知道它们存在于c#和。net中。
我们的生产代码不包含任何断言,我的问题是这个…
我应该开始在我们的生产代码中使用断言吗?如果可以,什么时候使用它最合适?这样做会更有意义吗
Debug.Assert(val != null, "message");
or
if ( val == null )
throw new exception("message");
当前回答
John Robbins在《调试Microsoft . net 2.0应用程序》一书中有一大节是关于断言的。他的主要观点是:
Assert liberally. You can never have too many assertions. Assertions don't replace exceptions. Exceptions cover the things your code demands; assertions cover the things it assumes. A well-written assertion can tell you not just what happened and where (like an exception), but why. An exception message can often be cryptic, requiring you to work backwards through the code to recreate the context that caused the error. An assertion can preserve the program's state at the time the error occurred. Assertions double as documentation, telling other developers what implied assumptions your code depends on. The dialog that appears when an assertion fails lets you attach a debugger to the process, so you can poke around the stack as if you had put a breakpoint there.
PS:如果你喜欢《代码完成》,我推荐你继续阅读这本书。我买这本书是为了学习如何使用WinDBG和转储文件,但前半部分包含了一些帮助避免bug的技巧。
其他回答
您应该使用Debug。断言来测试程序中的逻辑错误。编译器只能通知您语法错误。因此,您肯定应该使用Assert语句来测试逻辑错误。比如测试一个销售汽车的项目,只有蓝色的宝马可以得到15%的折扣。编译器不能告诉你你的程序在执行这个操作时逻辑上是否正确,但是assert语句可以。
仅在希望为发布版本删除检查的情况下使用断言。请记住,如果不在调试模式下编译,断言将不会触发。
对于检查为空的示例,如果这是在仅限内部的API中,我可能会使用断言。如果它在一个公共API中,我肯定会使用显式检查和抛出。
就其价值而言……我发现我的公共方法倾向于使用if () {throw;}模式,以确保方法被正确调用。我的私有方法倾向于使用Debug.Assert()。
The idea is that with my private methods, I'm the one under control, so if I start calling one of my own private methods with parameters that are incorrect, then I've broken my own assumption somewhere--I should have never gotten into that state. In production, these private asserts should ideally be unnecessary work since I am supposed to be keeping my internal state valid and consistent. Contrast with parameters given to public methods, which could be called by anyone at runtime: I still need to enforce parameter constraints there by throwing exceptions.
此外,如果某些东西在运行时不起作用(网络错误、数据访问错误、从第三方服务检索的坏数据等),我的私有方法仍然可以抛出异常。我的断言只是为了确保我没有破坏我自己关于对象状态的内部假设。
摘自《实用程序员:从熟练工到高手》
Leave Assertions Turned On There is a common misunderstanding about assertions, promulgated by the people who write compilers and language environments. It goes something like this: Assertions add some overhead to code. Because they check for things that should never happen, they'll get triggered only by a bug in the code. Once the code has been tested and shipped, they are no longer needed, and should be turned off to make the code run faster. Assertions are a debugging facility. There are two patently wrong assumptions here. First, they assume that testing finds all the bugs. In reality, for any complex program you are unlikely to test even a miniscule percentage of the permutations your code will be put through (see Ruthless Testing). Second, the optimists are forgetting that your program runs in a dangerous world. During testing, rats probably won't gnaw through a communications cable, someone playing a game won't exhaust memory, and log files won't fill the hard drive. These things might happen when your program runs in a production environment. Your first line of defense is checking for any possible error, and your second is using assertions to try to detect those you've missed. Turning off assertions when you deliver a program to production is like crossing a high wire without a net because you once made it across in practice. There's dramatic value, but it's hard to get life insurance. Even if you do have performance issues, turn off only those assertions that really hit you.
如果您希望在生产代码中使用断言(即发布构建),您可以使用Trace。Assert而不是Debug.Assert。
这当然会增加生产可执行文件的开销。
此外,如果您的应用程序在用户界面模式下运行,则默认情况下将显示断言对话框,这可能会让您的用户感到不安。
您可以通过删除DefaultTraceListener来覆盖这种行为:查看Trace的文档。MSDN中的侦听器。
总之,
使用调试。自由断言,以帮助在调试版本中捕获错误。 如果你使用Trace。在用户界面模式下断言,您可能希望删除DefaultTraceListener以避免让用户感到不安。 如果你测试的条件是你的应用程序无法处理的,你可能最好抛出一个异常,以确保执行不会继续。请注意,用户可以选择忽略断言。