关于这个.NET未处理的异常消息:

对象引用未设置为对象的实例.

为什么不呢.网络显示哪个对象是null

我知道我可以判断null并解决错误.然而,为什么不呢.NET帮助指出哪个对象有空引用,哪个表达式触发了NullReferenceException

推荐答案

(有关Visual Studio 2017中新的异常帮助程序的信息,请参阅本答案的结尾)


考虑这个代码:

String s = null;
Console.WriteLine(s.Length);

这将在第二行抛出NullReferenceException,你想知道为什么.NET并没有告诉您,当抛出异常时,s是空的.

要理解为什么你得不到这些信息,你应该记住,执行的不是C#source,而是IL:

IL_0001:  ldnull      
IL_0002:  stloc.0     // s
IL_0003:  ldloc.0     // s
IL_0004:  callvirt    System.String.get_Length
IL_0009:  call        System.Console.WriteLine

callvirt操作码抛出NullReferenceException,当计算堆栈上的第一个参数是空引用(使用ldloc.0加载的参数)时,它就会抛出NullReferenceException.

如果NET应该能够分辨出它是s,这是一个空引用.它应该以某种方式跟踪计算堆栈上的第一个参数来自s.在这种情况下,我们很容易看到s是空的,但如果该值是另一个函数调用的返回值,而不是存储在任何变量中,该怎么办?无论如何,这类信息并不是你想要在虚拟机中记录的.NET虚拟机.


要避免此问题,我建议您在所有公共方法调用中执行参数NULL判断(当然,除非您允许NULL引用):

public void Foo(String s) {
  if (s == null)
    throw new ArgumentNullException("s");
  Console.WriteLine(s.Length);
}

如果将NULL传递给该方法,您将得到一个准确描述问题所在的异常(即s为NULL).


四年后,Visual Studio2017现在有了一个新的异常帮助器,它将在抛出NullReferenceException时try 判断什么是NULL.当它是为空的方法的返回值时,它甚至能够为您提供所需的信息:

Visual Studio 2017 exception helper

请注意,这只适用于调试版本.

.net相关问答推荐

从没有流的EventStore中读取流不存在异常

[x.x.x,)在Packages.lock.json依赖项中是什么意思?

EF Core IEntityTypeConfigurations:从数据库提取数据后相关对象为空

如何为多种文件类型设置 FileSystemWatcher 过滤器?

C# - 获取不包括隐藏文件的文件列表

在 web api 控制器(.net 核心)中使用 async/await 或任务

使用 IIS Express 托管网站(临时)

(C# 7.2)私有保护修饰符的用例是什么?

序列化私有成员数据

调用委托与方法的性能

如何比较 C# 中的(目录)路径?

如何异步 Files.ReadAllLines 并等待结果?

返回 IList 是否比返回 T[] 或 List 更糟糕?

解密 .NET clr20r3 异常参数 P1..P10

将 SignalR 2.0 .NET 客户端重新连接到服务器集线器的最佳实践

找不到 System.Windows.Media 命名空间?

任何人都知道缺少枚举通用约束的好方法吗?

如何在不使用 3rd 方库的情况下登录 C#?

我可以将构造函数参数传递给 Unity 的 Resolve() 方法吗?

如何修改 KeyValuePair 值?