C# 我可以更清楚地说明NullReferenceException吗?

C# 我可以更清楚地说明NullReferenceException吗?,c#,C#,只有通过查看错误(问题窗口)才能知道引发NullReferenceException的变量的名称。不,这是不可能的 与程序员代码引发的异常(如ArgumentNullException或InvalidOperationException)不同,NullReferenceException由运行时本身引发。它发生在携带变量名不切实际的级别。您的错误检查代码通过确保满足前提条件来保护“有效负载”代码。这就是您如何预测使用您的代码的程序员可能会犯的潜在错误: void DoSomething(stri

只有通过查看错误(问题窗口)才能知道引发NullReferenceException的变量的名称。

不,这是不可能的

与程序员代码引发的异常(如
ArgumentNullException
InvalidOperationException
)不同,
NullReferenceException
由运行时本身引发。它发生在携带变量名不切实际的级别。您的错误检查代码通过确保满足前提条件来保护“有效负载”代码。这就是您如何预测使用您的代码的程序员可能会犯的潜在错误:

void DoSomething(string arg1, string arg2) {
    if (arg1 == null) throw new ArgumentNullException(nameof(arg1));
    if (arg2 == null) throw new ArgumentNullException(nameof(arg2));
    ...
}
与您的代码不同,运行时不能枚举所有的前提条件而不会变得不切实际。即使在一个相对简单的表达式中,可能导致
NullReferenceException
的事情也相当多:

retObj.Result.List = myObj.Process().FirstOrDefault().ToList();
C#需要为以下各项准备一条错误消息:

  • retObj
  • retObj.Result
  • myObj
  • myObj.Process()
  • myObj.Process().FirstOrDefault()
这是一行代码的五个字符串

此外,C#需要在发布代码中以不同的方式处理此问题,以避免泄露黑客可能利用的代码内容。带有
NullReferenceException
的错误消息详细说明了导致错误的表达式,可能会告诉黑客您正在使用特定的API或库,他们可能已经准备好利用该API或库进行攻击

由于
NullReferenceException
最终是一个指示编程错误的错误,因此您应该添加自己的检查,以确保无论向代码传递了什么参数,代码都不会抛出它。空检查参数并确保内部状态一致不仅有助于消除
NullReferenceException
s,而且还可以通过明确列出其前提条件使代码更易于理解


注意:Visual Studio 2017调试器可以帮助您找出异常的原因,并使用该功能。不过,它也有一些限制:代码必须针对.NET版本4.6.2或更高版本进行编译,而不是针对UWP或.NET内核,并且没有JIT优化(感谢您的精彩评论)

VS应该指出异常触发的位置,至少向我们提供一些代码。简短的答案是否定的。较长的答案需要一个。您假设有一个变量名。给定
a.Foo().bar
,完全可能
a
为非null,但
a.Foo()
返回null。在这种情况下,你在寻找什么样的东西?新的空引用分析功能感谢@dasblinkenlight提供了信息丰富的答案。我想从现在起,我将确保我的代码永远不会抛出NullReferenceException。