允许出现 NullReferenceExceptions 的可能性是一件坏事吗?
我正在使用 Pex 和 Moles,运行 Pex 后发现几乎所有 Pex 所说失败的测试都是因为 NullReferenceExceptions 被“允许”。阅读 Pex 文档,我发现了以下内容:
如果更高级别的组件通过 将格式错误的数据传送到较低级别 组件,其中较低级别 组件拒绝,然后 更高级别的组件应该是 一开始就阻止这样做 地点。
因此,上面的建议是,我们应该在调用其他方法/类之前测试空值,使用以下内容:
if(foo == null)
throw new ArgumentNullException("its null and this shouldn't happen")
else
Bar(foo); //won't get a null reference exception here because we checked first...
恕我直言,检查空值对于性能和代码膨胀的原因来说并没有多大吸引力,但我想听听是什么其他人不得不说......
I'm playing with Pex and Moles and after running Pex found that nearly all the tests that Pex said failed were because NullReferenceExceptions were "allowed". Reading the Pex documentation, I came across the following:
If a higher-level component passes
malformed data to a lower-level
component, which the lower-level
component rejects, then the
higher-level component should be
prevented from doing so in the first
place.
So what the above is suggesting is that we should test for nulls before other methods/classes are called using something like:
if(foo == null)
throw new ArgumentNullException("its null and this shouldn't happen")
else
Bar(foo); //won't get a null reference exception here because we checked first...
IMHO checking for nulls all over doesn't appeal that much for performance and also code bloat reasons but I would like to hear what other people have to say....
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
是的,在我看来,你应该在使用你的论点之前验证它们。
当使用意外空值时,应该发生
NullReferenceException
。它永远不应该显式抛出,并表明最终抛出它的方法或其调用的方法级别存在问题。ArgumentNullException
表示调用堆栈中比抛出该错误的方法更早的方法中存在错误。 (通常,但并非总是,直接调用者。)越早抛出指示问题的异常,就越容易查明 null 值首先出现的位置 出现这种情况的可能性就越小“坏数据”将在其他地方产生令人讨厌的影响(例如,在意识到数据实际上为空之前覆盖准备将数据写入其中的文件)。
如果您对如何调用内部或私有方法有信心,那么不执行检查可能是合适的,但对于公共方法,我相信参数验证几乎总是合适的。
Yes, you should validate your arguments before using them, IMO.
NullReferenceException
should occur when an unanticipated null value is used. It should never be thrown explicitly, and indicates a problem at the level of the method which ends up throwing it, or something it's called.ArgumentNullException
indicates a bug in a method earlier in the call stack than the method throwing it. (Usually, but not always, the direct caller.)The earlier you throw an exception indicating a problem, the easier it will be to pinpoint where the null value first crept in and the less likely it is that the "bad data" will have had a nasty effect elsewhere (e.g. overwriting a file ready to write data into it before realising that actually the data is null).
If you're confident in how you call your internal or private methods, it may be appropriate to not perform checking there, but for public methods I believe argument validation is pretty much always appropriate.
是的,我同意。 NullReferenceException 是尝试调用空引用变量成员的结果。这意味着没有适当的安全措施来验证调用该成员的操作是否合法,在我看来这是一件坏事。您应该始终不信任输入,并在使用之前验证它是否可以安全使用。
Yes, I would agree. A
NullReferenceException
is the result of an attempt to invoke a member on a variable that is a null reference. This means that there are no safe-guards in place to verify that it is a legal operation to invoke the member, and this is a bad thing in my eyes. You should always distrust input and verify that it is safe for you to use, before using it.当参数传递给公开服务的函数时,检查 NULL 始终是一个好习惯。其余的 NULL 检查属于常识,但这样做很有用,您基本上可以使用辅助方法来完成它。
最烦人的 NULL 检查是对字符串的检查。它们可能非常令人讨厌,但我使用扩展方法来克服这个问题:
所以你可以使用:
It is always a good practice to check for NULL when parameters are passed to a function which is exposing a service. Rest of NULL checking is down to common sense but it is useful to do and you can basically use a helper method to do it.
The most annoying NULL checking is with the strings. They can be quite nasty but I use an extension method to overcome that:
So you can use:
即使从简单的诊断角度来看,您可以获得哪些更多信息 -
NullReferenceException 还是 ArguementNullException?
更进一步,将堆栈跟踪从图片中删除。您的两条消息可能是:
NullReferenceException:
“你调用的对象是空的。”
ArguementNullException:
“System.ArgumentNullException:MyVariable 不能为空。”
另外,检查语法并阅读有关应传递给 ArgumentNullException 构造函数的内容的信息。
这是不对的。
没错。
Even from a simple diagnostic perspective, what can you get more information about -
A NullReferenceException or an ArguementNullException?
Take it a step further and take the stack trace out of the picture. Your two messages are probably:
NullReferenceException:
"Object reference not set to an instance of an object."
ArguementNullException:
"System.ArgumentNullException: MyVariable cannot be null."
Also, check your syntax and read the info on what you are supposed to pass to the ArgumentNullException constructor.
That is not right.
That is right.