121

以下は、== 演算子のオーバーロード メソッドで無限再帰を引き起こします。

    Foo foo1 = null;
    Foo foo2 = new Foo();
    Assert.IsFalse(foo1 == foo2);

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

null をチェックするにはどうすればよいですか?

4

13 に答える 13

146

使用ReferenceEquals:

Foo foo1 = null;
Foo foo2 = new Foo();
Assert.IsFalse(foo1 == foo2);

public static bool operator ==(Foo foo1, Foo foo2) {
    if (object.ReferenceEquals(null, foo1))
        return object.ReferenceEquals(null, foo2);
    return foo1.Equals(foo2);
}
于 2008-09-16T15:41:17.013 に答える
20

オーバーロード メソッドでオブジェクトにキャストします。

public static bool operator ==(Foo foo1, Foo foo2) {
    if ((object) foo1 == null) return (object) foo2 == null;
    return foo1.Equals(foo2);
}
于 2008-09-16T15:40:56.467 に答える
8

を使用しReferenceEqualsます。MSDN フォーラムから:

public static bool operator ==(Foo foo1, Foo foo2) {
    if (ReferenceEquals(foo1, null)) return ReferenceEquals(foo2, null);
    if (ReferenceEquals(foo2, null)) return false;
    return foo1.field1 == foo2.field2;
}
于 2008-09-16T15:51:27.347 に答える
4

オーバーライドbool Equals(object obj)して、演算子が必要で、同じ値==Foo.Equals(object obj)返す場合、通常は次の!=ように演算子を実装します。

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

オペレーターは、すべての null チェックを行った後、2 つが等しい場合に実際のチェックを行うためにオーバーライドしたことを==呼び出します。foo1.Equals(foo2)

于 2008-09-17T10:18:27.560 に答える
4

試すObject.ReferenceEquals(foo1, null)

とにかく、==演算子をオーバーロードすることはお勧めしません。参照の比較に使用Equalsし、「意味論的」比較に使用する必要があります。

于 2008-09-16T15:42:46.760 に答える
1

私のアプローチはすることです

(object)item == null

object私は、間違いのない独自の等値演算子に依存しています。または、カスタム拡張メソッド (およびオーバーロード):

public static bool IsNull<T>(this T obj) where T : class
{
    return (object)obj == null;
}

public static bool IsNull<T>(this T? obj) where T : struct
{
    return !obj.HasValue;
}

または、より多くのケースを処理するには、次のようになります。

public static bool IsNull<T>(this T obj) where T : class
{
    return (object)obj == null || obj == DBNull.Value;
}

制約によりIsNull、値の型が妨げられます。今では呼ぶほど甘い

object obj = new object();
Guid? guid = null; 
bool b = obj.IsNull(); // false
b = guid.IsNull(); // true
2.IsNull(); // error

これは、全体を通して null をチェックする一貫した/エラーが発生しにくいスタイルを 1 つ持っていることを意味します。(object)item == nullまた、 がよりも非常にわずかに高速であるObject.ReferenceEquals(item, null)こともわかりましたが、それが重要な場合のみです (現在、すべてをマイクロ最適化する作業を行っています!)。

等価チェックの実装に関する完全なガイドを参照するには、参照型の 2 つのインスタンスを比較するための "ベスト プラクティス" とは? を参照してください。

于 2012-12-16T08:13:26.553 に答える
-5

オブジェクト プロパティを使用して、結果の NullReferenceException をキャッチすることができます。試したプロパティがオブジェクトから継承またはオーバーライドされている場合、これはどのクラスでも機能します。

public static bool operator ==(Foo foo1, Foo foo2)
{
    //  check if the left parameter is null
    bool LeftNull = false;
    try { Type temp = a_left.GetType(); }
    catch { LeftNull = true; }

    //  check if the right parameter is null
    bool RightNull = false;
    try { Type temp = a_right.GetType(); }
    catch { RightNull = true; }

    //  null checking results
    if (LeftNull && RightNull) return true;
    else if (LeftNull || RightNull) return false;
    else return foo1.field1 == foo2.field2;
}
于 2008-09-16T15:58:53.710 に答える