簡體   English   中英

為什么我要在Equals覆蓋中執行object.ReferenceEquals(null,this)?

[英]Why would I ever want to do object.ReferenceEquals(null, this) in Equals override?

請考慮以下我正在審核的代碼:

public override bool Equals(object other)
{
    return !object.ReferenceEquals(null, this)
           && (object.ReferenceEquals(this, other)
           || ((other is MyType) && this.InternalEquals((MyType)other)));
}

這段代碼的第一行引發了我的好奇心。 只要this為null,該方法應返回false。 現在我非常確定程序員打算寫一個!object.ReferenceEquals(other, null) ,以使用null來快捷方式,但他堅持認為this可以為null。 我堅持認為它不能(除非有人使用直接內存操作)。 我們應該留下嗎?

雖然我肯定不會正常檢查this為無效,這是可能的,沒有任何實際的內存污穢-只是有點反思:

using System;

public class Test
{
    public void CheckThisForNullity()
    {
        Console.WriteLine("Is this null? {0}", this == null);
    }

    static void Main(string[] args)
    {
        var method = typeof(Test).GetMethod("CheckThisForNullity");
        var openDelegate = (Action<Test>) Delegate.CreateDelegate(
               typeof(Action<Test>), method);
        openDelegate(null);
    }
}

或者,生成IL,它使用call而不是callvirt來調用null目標上的實例方法。 完全合法,不是C#編譯器通常會做的事情。

這與終結無關,終結本身就是毛茸茸的,但卻以不同的方式。 如果CLR可以證明你不會使用實例中的任何字段 (我強烈希望包含this引用) ,那么在實例方法執行時可以運行終結器。

至於提供的代碼 - 不,這看起來只是一個錯誤。 我會把它重寫為:

public override bool Equals(object other)
{
    return Equals(other as MyType);
}

public bool Equals(MyType other)
{
    if (ReferenceEquals(other, null))
    {
        return false;
    }
    // Now perform the equality check
}

...假設MyType是一個類,而不是一個結構。 注意我是如何使用具有正確參數類型的另一個公共方法 - 我同時實現IEquatable<MyType>

C#通常不允許在null上調用方法。 我認為這是誰寫的,程序員無論是從C ++背景的(這里我認為方法可以被稱為null的,只要他們不訪問的數據成員this )或寫防守特殊情況下(如調用通過反思,正如已經說過的那樣)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM