【问题标题】:Why NullReferenceException is thrown in overriden Object.Equals method?为什么在覆盖的 Object.Equals 方法中抛出 NullReferenceException?
【发布时间】:2012-10-20 05:52:26
【问题描述】:

我刚刚在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# .net clr


【解决方案1】:

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

托管 C++ 是调用指令的最著名用户。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-25
    • 2010-09-27
    • 2014-03-07
    • 1970-01-01
    • 2011-02-13
    相关资源
    最近更新 更多