允许出现 NullReferenceExceptions 的可能性是一件坏事吗?

发布于 2024-10-23 21:00:32 字数 538 浏览 2 评论 0原文

我正在使用 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

潇烟暮雨 2024-10-30 21:00:32

是的,在我看来,你应该在使用你的论点之前验证它们。

当使用意外空值时,应该发生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.

朕就是辣么酷 2024-10-30 21:00:32

是的,我同意。 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.

她如夕阳 2024-10-30 21:00:32

当参数传递给公开服务的函数时,检查 NULL 始终是一个好习惯。其余的 NULL 检查属于常识,但这样做很有用,您基本上可以使用辅助方法来完成它。

最烦人的 NULL 检查是对字符串的检查。它们可能非常令人讨厌,但我使用扩展方法来克服这个问题:

public static class StringExtensions
{
    public static string NullSafe(this string s)
    {
        return s ?? string.Empty;
    }
}

所以你可以使用:

myString.NullSafe().ToUpper()

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:

public static class StringExtensions
{
    public static string NullSafe(this string s)
    {
        return s ?? string.Empty;
    }
}

So you can use:

myString.NullSafe().ToUpper()
挖个坑埋了你 2024-10-30 21:00:32

即使从简单的诊断角度来看,您可以获得哪些更多信息 -
NullReferenceException 还是 ArguementNullException

更进一步,将堆栈跟踪从图片中删除。您的两条消息可能是:

NullReferenceException:
“你调用的对象是空的。”

  • 有些东西是空的,在某个地方,我可能没想到它会这样。
  • 我可能需要调试才能找到错误。

ArguementNullException:
“System.ArgumentNullException:MyVariable 不能为空。”

  • 我知道某些 null 值被传递给了方法。
  • 有可能,通过变量名称,我可以将其范围缩小到
  • 我仍然可能需要调试的一组较小的可能方法,但我应该能够知道一些放置断点的一般位置。

另外,检查语法并阅读有关应传递给 ArgumentNullException 构造函数的内容的信息。

throw new ArgumentNullException("its null and this shouldn't happen");

这是不对的。

throw new ArgumentNullException("VariableName");

没错。

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."

  • Something is null, somewhere and I probably did not expect it to be.
  • I probably need to debug to find the error.

ArguementNullException:
"System.ArgumentNullException: MyVariable cannot be null."

  • I know that something null was passed to a method.
  • Chances are, by the variable name, I can narrow it down to a smaller set of possible methods
  • I still probably need to debug, but I should be able know some general places to put a breakpoint.

Also, check your syntax and read the info on what you are supposed to pass to the ArgumentNullException constructor.

throw new ArgumentNullException("its null and this shouldn't happen");

That is not right.

throw new ArgumentNullException("VariableName");

That is right.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文