7

重複の可能性:
無限再帰なしで'=='演算子のオーバーロードでnullをチェックするにはどうすればよいですか?

オブジェクトの==演算子をオーバーロードするとき、私は通常次のように記述します。

    public static bool operator ==(MyObject uq1, MyObject uq2) {
        if (((object)uq1 == null) || ((object)uq2 == null)) return false;
        return uq1.Field1 == uq2.Field1 && uq1.Field2 == uq2.Field2;
    }

反対するためにダウンキャストしない場合、関数はそれ自体に再帰しますが、より良い方法がないかどうか疑問に思う必要がありますか?

4

7 に答える 7

7

マイクロソフトが言うように、

operator == のオーバーロードでよくあるエラーは、(a == b)、(a == null)、または (b == null) を使用して参照の等価性をチェックすることです。これにより、オーバーロードされた演算子 == が呼び出され、無限ループが発生します。ループを回避するには、ReferenceEquals を使用するか、型を Object にキャストします。

したがって、ReferenceEquals(a, null) || を使用します。ReferenceEquals(b, null) は 1 つの可能性ですが、オブジェクトへのキャストも同様に優れています (実際には同等だと思います)。

はい、もっと良い方法があるはずですが、使用する方法は推奨される方法です。

ただし、指摘されているように、== をオーバーライドする場合は、Equals もオーバーライドする必要があります。LINQ プロバイダーはさまざまな言語で記述されており、実行時に式の解決を行っているため、すべてのコードを自分で所有している場合でも、式の解決を行わないと困る場合があります。

于 2008-09-17T20:05:03.953 に答える
2

ReferenceEquals(オブジェクト obj1, オブジェクト obj2)

于 2008-09-17T19:55:40.077 に答える
2

@ neouser99: それは正しい解決策ですが、見落とされている部分は、等値演算子 (演算子 ==) をオーバーライドするときに、Equals 関数もオーバーライドして、単に演算子に関数を呼び出させる必要があることです。すべての .NET 言語が演算子のオーバーロードをサポートしているわけではないため、Equals 関数をオーバーライドする理由があります。

于 2008-09-17T20:03:25.330 に答える
0

Resharper を使用して、Equals および GetHashCode メソッドを作成するだけです。この目的のために最も包括的なコードを作成します。

更新 意図的に投稿したわけではありません-コードはクラスごとに異なるため、コピーアンドペーストではなくResharperの機能を使用することをお勧めします。Resharper を使わずに C# を開発することに関しては、あなたの生き方がわかりません。

とにかく、これは単純なクラスのコードです(古いバージョンのResharper 3.0によって生成されました-私は4.0を使用していますが、現在、同一のコードが作成されるかどうかは覚えていません)

public class Foo : IEquatable<Foo>
{
    public static bool operator !=(Foo foo1, Foo foo2)
    {
        return !Equals(foo1, foo2);
    }

    public static bool operator ==(Foo foo1, Foo foo2)
    {
        return Equals(foo1, foo2);
    }

    public bool Equals(Foo foo)
    {
        if (foo == null) return false;
        return y == foo.y && x == foo.x;
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(this, obj)) return true;
        return Equals(obj as Foo);
    }

    public override int GetHashCode()
    {
        return y + 29*x;
    }

    private int y;
    private int x;
}
于 2008-09-17T20:38:28.383 に答える
-1

しかし、オブジェクト メンバー関数を作成してみませんか? Null 参照で呼び出すことはできないので、最初の引数が Null でないことは確かです。

確かに、二項演算子の対称性は失われますが、それでも...

(Purfideas の回答に関する注意: 配列のセンチネル値として必要な場合、Null は Null と等しい可能性があります)

== 関数のセマンティクスについても考えててください。

  • ID (同じオブジェクトを指す)
  • 価値の平等
  • 等価 (例: 1.000001 は .9999999 と等価)
于 2008-09-17T20:06:07.383 に答える
-1
if ((object)uq1 == null) 
    return ((object)uq2 == null)
else if ((object)uq2 == null)
    return false;
else
    //return normal comparison

これは、両方が null の場合に等しいと比較します。

于 2008-09-17T19:58:20.333 に答える
-1

DB 処理に従います。

null == <anything> is always false
于 2008-09-17T20:00:13.560 に答える