为什么 .net 中的对象引用错误异常不告诉我哪个对象为空?
也许问这个问题暴露了我对这个过程缺乏了解,但话又说回来,没有更好的理由来问了!
跟踪这些可能会令人沮丧,因为堆栈跟踪可以帮助我知道从哪里开始查找,但不知道哪个对象为空。
这里到底发生了什么?是因为变量名称没有捆绑在可执行文件中吗?
Maybe asking the question betrays my lack of knowledge about the process, but then again, there's no better reason to ask!
Tracking these down can be frustrating because stack traces can help me know where to start looking but not which object was null.
What is going on under the hood here? Is it because the variable names aren't bundled in the executable?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
使用全面优化构建的 .NET 代码,没有调试信息:您的局部变量名称消失了,某些局部变量可能已被完全消除。
使用完全优化+ PDB(或完全调试)构建的.NET代码:保留大多数局部变量名称,一些局部变量可能已被消除
无优化+无调试信息:局部变量名称消失了。
然后我们必须考虑到您正在处理的任何内容可能根本不在局部变量中 - 它可能是先前函数调用的结果,您在该函数调用上链接了一个新函数调用。
.NET code built with full optimizations and no debug info: your local variable names are gone, some local variables may have been eliminated entirely.
.NET code built with full optimizations + PDB (or full debug): most local variable names preserved, some local variables may have been eliminated
No optimizations + no debug info: local variable names are gone.
And then we have to consider that whatever you're dealing with may not be in a local variable at all - it might have been the result of a previous function call, on which you're chaining a new function call.
基本上你回答了你自己的问题。当您的代码被编译时,它会被转换为中间语言(IL)。 IL 不像代码那样具有变量名,被调用方法的参数在调用该方法之前被推送到堆栈,并且当前方法参数和局部变量由该位置引用。我相信这是因为这个结构有助于 JIT 编译器生成代码。
pdb 符号文件存储生成的 IL 和代码之间的映射。它用于告诉您调用堆栈中的每个方法调用引用代码中的哪一行。可能这里存储的信息不够详细,无法说明哪个变量为空,或者可能只是认为执行此操作的性能太昂贵。无论如何,如果您允许编译器优化生成的 IL,则 IL 中的变量与代码中的变量之间可能不再存在一对一的映射。
希望有帮助,
抢
Basically you answered your own question. When you're code is compiled it's transformed in intermediate language (IL). IL does not have variable names the way your code does, arguments to a method being called are pushed on to a stack before the method is called and the currents methods arguments and local variables are referred to by there position. I believe this is because this structure aids the JIT compiler generate code.
The pdb symbols file stores a mapping between the IL generated and your code. It is used to tell you which line in your code each method call in the call stack refers to. Possibly the information stored here isn't detailed enough to say which variable is null, or possibly it was just considered too expensive in terms when of perf to be able to do this. In any case, if you have allowed the compiler to optimize the IL generated there may no longer be a one to one mapping between the variables in the IL and the variables in your code.
Hope that helps,
Rob
没有“对象标识符”。 .NET 不可能说“标识符为 xxxx 的对象为 null”。
您将学习如何不犯这些错误,不用担心。只需将表达式分解为更小的部分,您就会找到忘记初始化的对象。您将学会在这种情况下初始化它们,一段时间后,这种情况就不会再发生了。
There is no "object identifier". There's no way that .NET could say "the object with identifier xxxx is null".
You'll learn how to not make these mistakes, don't worry. Just break down your expressions into smaller pieces, and you'll find which objects you forgot to initialize. You'll learn to iniitialize them in that scenario, and after a while, that case won't happen again.