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

时间:2012-10-20 05:52:26

标签: 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);
}

在第二行,如果这= = null,则抛出NullReferenceException。那么如何调用null对象的方法呢?

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强制方法?或者是其他东西?

感谢。

1 个答案:

答案 0 :(得分:4)

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

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

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