4

値型 (構造体) の "Equals" の既定の動作では、リフレクションを使用して 2 つの値の内容を比較しているため、パフォーマンスが重要な場合は、効率のために Equals 演算子をオーバーライドすることをお勧めします。

しかし、Equals の署名は次のようです。

public override bool Equals( object ob )

つまり、このメソッドをオーバーライドしても、値の型を比較す​​るとボックス化が発生します。これは、パラメーターが「オブジェクト」型でなければならないためです。

私は正しいですか?ボクシングは発生しますか?値の型には == 演算子のみを使用する必要がありますか?

編集:そしてちょっとした質問ですが、== をオーバーライドすると、静的ではなく「これ」を 1 つのパラメーターと比較するより直感的な形式ではなく、静的で 2 つのパラメーターを取得する必要があるのはなぜですか?

4

1 に答える 1

8

オーバーライドに加えて、Object.Equals()を実装する必要があります。タイプ自体は IEquatable<T>どこにありますか。type の引数を受け入れます。TIEquatable<T>.Equals()T

インターフェイスを暗黙的に実装する場合 (そしてなぜ実装しないのですか?)、可能な場合はT-typed 引数を受け入れるより具体的なメソッドが使用され、この場合、ボックス化は発生しません。(これは、インターフェースをオーバーロードして実装しない場合に当てはまりますEquals()が、この場合、インターフェースを実装しない理由はありません。)

これは、値型の等価性を実装するときに通常使用するパターンです。

struct Foo : IEquatable<Foo>
{
    public bool Equals(Foo other)
    {
        // Do your equality test here.
        throw new NotImplementedException();
    }

    public override bool Equals(object other)
    {
        if (other != null && other is Foo) {
            return Equals((Foo)other);
        }

        return false;
    }

    // If you also want to overload the equality operator:
    public static bool operator==(Foo a, Foo b)
    {
        return a.Equals(b);
    }

    public static bool operator!=(Foo a, Foo b)
    {
        return !a.Equals(b);
    }
}

もちろん、オーバーライドすることも忘れないでくださいObject.GetHashCode()


Equals(object)メソッドを使用する場合、引数のみがボックス化されることに注意してください。呼び出しているオブジェクトは、最初に (またはインターフェイス タイプに)変換しない限り、ボックス化されません。、、または命令objectの 1 つが(必要に応じて) 呼び出したオブジェクトに対して発行され、もう 1 つはボックス化されます (より具体的なオーバーロードがない場合)。ldlocaldfldaldsflda

于 2013-03-22T19:01:02.197 に答える