2016-10-06 8 views
0

operator==をクラスの1つに実装しようとしています。ステップの著書のMicrosoft Visual C#ステップによると、私はそうのようにそれを書く必要があります:lhsはラインlhs.Equals(rhs)にnullであるため、operator ==を実装するときにNullReferenceExceptionを避けるには

using System; 
using System.Diagnostics; 

namespace EqualTest2 
{ 
    public class EqualTestClass 
    { 
     public double _x1; 

     public EqualTestClass(double x1) 
     { 
      _x1 = x1; 
     } 

     public override bool Equals(object other) 
     { 
      if (other is EqualTestClass) 
      { 
       return (Math.Abs(_x1 - ((EqualTestClass)other)._x1) < 1e-6); 
      } 
      return false; 
     } 

     public override int GetHashCode() 
     { 
      return base.GetHashCode(); 
     } 

     public static bool operator ==(EqualTestClass lhs, EqualTestClass rhs) 
     { 
      return lhs.Equals(rhs); 
     } 

     public static bool operator !=(EqualTestClass lhs, EqualTestClass rhs) 
     { 
      return !lhs.Equals(rhs); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      EqualTestClass test1 = new EqualTestClass(1.0); 
      EqualTestClass test2 = new EqualTestClass(1.0); 
      EqualTestClass test3 = new EqualTestClass(2.0); 
      EqualTestClass test4 = null; 

      Debug.WriteLine("1: {0}", test1 == test2); 
      Debug.WriteLine("2: {0}", test1 == test3); 
      Debug.WriteLine("3: {0}", test1 == test4); 
      Debug.WriteLine("4: {0}", test4 == test1); 
     } 
    } 
} 

このプログラムは、第四デバッグライン上NullReferenceExceptionをスローします。私はif (lhs != null)operator==に入れることができないため、無限再帰が発生する(ブックの警告として)。

public static bool operator ==(EqualTestClass lhs, EqualTestClass rhs) 
    { 
     try 
     { 
      return lhs.Equals(rhs); 
     } 
     catch (NullReferenceException) 
     { 
      return false; 
     } 
    } 

    public static bool operator !=(EqualTestClass lhs, EqualTestClass rhs) 
    { 
     try 
     { 
      return !lhs.Equals(rhs); 
     } 
     catch (NullReferenceException) 
     { 
      return false; 
     } 
    } 

は(私はC#は喜んlhs場合はnilを返します[lhs method:argument]のObjective Cの背景から来るに新たなんだ。だから私のクラスのヌルインスタンスを比較するときに例外を避けるために、私はこれに実装を変更しましたこのような例外は発生しません)。

この例外ベースの実装は、イディオム的に正しいですか?

答えて

1

あなたのケースではtry-catchブロックを使用しないでください。あなたはこれにあなたのオペレータを変更するだけで済みます:

public static bool operator ==(EqualTestClass lhs, EqualTestClass rhs) 
{ 
    return object.Equals(lhs, rhs); 
} 
public static bool operator !=(EqualTestClass lhs, EqualTestClass rhs) 
{ 
    return !object.Equals(lhs, rhs); 
} 

まだあなたオーバーライドさEquals()メソッドの呼び出し中にこれがあなたのために、ヌル・チェックを行います。 System.Object.Equals()のソースコードによると:それはあなたの問題の世話をするように

public static bool Equals(Object objA, Object objB) 
{ 
    if (objA==objB) { 
     return true; 
    } 
    if (objA==null || objB==null) { 
     return false; 
    } 
    return objA.Equals(objB); 
} 

が見えます。

0

あなたが参照で引数を比較する必要があります。

if (!ReferenceEquals(lhs, null)) ... 
3

平等をチェックする前に、あなたの引数のそれぞれについて、ヌルのための参照をチェックするReferenceEquals(lhs, null)を使用することを検討して

0

単に

最初のNULLテストを行います
if(lhs == null || rhs == null){ 

あなたが望むように処理してください。 (nullを返す場合はtrue、そうでない場合はtrue)

.equals()はオブジェクトを必要とし、ヌルオブジェクトで呼び出すとNullPointerをスローします。しかし、==うまく動作します。

関連する問題