我可以使NullReferenceException更清楚吗?

时间:2018-08-12 12:10:10

标签: c#

仅通过查看错误(问题窗口),是否有可能知道导致引发NullReferenceException的变量的名称。

1 个答案:

答案 0 :(得分:10)

不,这不可能。

与程序员代码引发的异常(例如ArgumentNullExceptionInvalidOperationException不同,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或库,他们可能已经准备好利用它们。

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

注意:Visual Studio 2017调试器可以通过Null Reference Analysis功能帮助您找出异常原因。但是,它带有一些限制:代码必须针对.NET 4.6.2或更高版本进行编译,而不是针对UWP或.NET Core,并且不进行JIT优化(感谢Hans Passant)。