为什么在覆盖 Object.Equals 方法时会抛出 NullReferenceException?

4
我在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会强制绕过任何检查来调用方法吗?还是其他原因?感谢您。

请查看此问题:https://dev59.com/TGkv5IYBdhLWcg3wZwC- - empi
为什么要检查this是否为空? - Amit Mittal
1个回答

4

C#在进入空对象之前确实使用callvirt,这可能会导致NullReferenceException。但是由于BCL适用于众多编程语言,他们在一些中心部件(例如字符串)中确保针对空对象进行了保护,这些部件确实使用了call指令。

Managed C++是最显著的call指令用户。

这样做有助于调试(据我所知),但这并不在整个BCL中都是一致的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接