c# - 为什么在重写的 Object.Equals 方法中抛出 NullReferenceException?

标签 c# .net clr

我刚刚在dotPeek, String.cs 中找到了它:

[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
[__DynamicallyInvokable]
public override bool Equals(object obj)
{
  if (this == null)
    throw new NullReferenceException();
  string strB = obj as string;
  if (strB == null)
    return false;
  if (object.ReferenceEquals((object) this, obj))
    return true;
  if (this.Length != strB.Length)
    return false;
  else
    return string.EqualsHelper(this, strB);
}

在第二行,如果 this == null,则抛出 NullReferenceException。那么怎么可能调用空对象的方法呢?

MSDN 说: 请注意,应用程序会抛出 ArgumentNullException 异常,而不是此处讨论的 NullReferenceException 异常。

以下 Microsoft 中间语言 (MSIL) 指令抛出 NullReferenceException:

callvirt
cpblk
cpobj
initblk
ldelem.<type>
ldelema
ldfld
ldflda
ldind.<type>
ldlen
stelem.<type>
stfld
stind.<type>
throw
unbox

如果我得到它,异常将在进入方法体之前抛出。正确的?那么什么需要从方法中抛出 NullReferenceException 呢? __DynamicallyInvokableAttribute 是否强制调用绕过任何检查的方法?或者是其他东西?

谢谢。

最佳答案

C# 确实使用了 callvirt,您在输入空对象之前会得到一个 NullReferenceException。但是由于 BCL 是为多种语言制作的,所以它们确实在某些使用调用指令的中心部分(例如字符串)中防止了空对象。

托管 C++ 是 call 指令最值得注意的用户。

这样做是为了帮助调试(据我所知),但它在整个 BCL 中并不一致。

关于c# - 为什么在重写的 Object.Equals 方法中抛出 NullReferenceException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12985679/

相关文章:

c# - Owin Websockets - 了解 IOwinContext 和 WebSocketAccept

.net - CorFlags.exe、System.Data.SQLite.dll 和 BadImageFormatException

c# - .net值类型初始化

c# - 如何在 C# 中获取服务器和客户端之间的延迟?

c# - Arc 不显示在 wpf Canvas 上?

c# - 限制文件/文件夹写入指定根以外的路径

asp.net - 为什么 Aspx 页面在 javascript 调用后重新加载

c# - 有没有一种简单的方法可以找到与输入控件相关的验证器?

c# - 任务并行库时间分片

c# - 运行时尝试查找 exe/dll 而不是 .winmd 引用