2017-02-01 10 views
0

GetHashCode()方法を実装するために、数値フィールドを使用Equals(object)GetHashCode()をオーバーライドする方法を示すリソースのすべて:フィールドとして数字を使わずにGetHashCode()をオーバーライドするにはどうすればよいですか?

Implementing the Equals Method
What's the best strategy for Equals and GetHashCode?
Why is it important to override GetHashCode when Equals method is overridden?

をしかし、私のクラスでは、私は任意の数値を持っていませんフィールド。それは親、子供、およびデータなどのインタフェースを参照して、ツリー内のノードである:

public class Node 
{ 
    private IInterface myInterface; 
    private Node parent; 
    private List<Node> children = new List<Node>(); 

    public override bool Equals(object obj) 
    { 
     if (obj == null || GetType() != obj.GetType()) 
     { 
      return false; 
     } 
     var node = (Node)obj; 
     return myInterface == node.myInterface; 
    } 

    public override int GetHashCode() 
    { 
     ??? 
    } 
} 

私はハッシュコードを設定する必要がありますか?

答えて

6

Equals実装によると、2つのNodeのインスタンスがあれば等しく、そのmyInterfaceが等しい場合にのみ:myInterfaceGetHashCodeための唯一の源である理由

public override bool Equals(object obj) 
{ 
    if (obj == null || GetType() != obj.GetType()) 
    { 
     return false; 
    } 
    var node = (Node)obj; 

    // instances are equal if and only if myInterface's are equal 
    return myInterface == node.myInterface; 
} 

だこと:

public override int GetHashCode() 
{ 
    return null == myInterface ? 0 : myInterface.GetHashCode(); 
} 

P.S.編集、クリスVandermottenのおかげで)多くの場合、それは潜在的にmyInterface秒かかる時間/リソースを比較する前にEquals実装でReferenceEqualsをチェックするとよいでしょう:

public override bool Equals(object obj) { 
    // Easy tests: 
    // 1. If "this" and "obj" are in fact just the same reference? 
    // 2. Since `Node` (or Equals) is not sealed, the safiest is to check types 
    if (object.ReferenceEquals(this, obj)) 
    return true; 
    else if (null == obj || other.GetType() != GetType()) 
    return false; 

    // Potentially time/resource cosuming (we don't know IInterface implementation) 
    return ((Node) obj).myInterface == myInterface; 
} 
+1

あなた 'Equals'方法はチェックしませんタイプ平等。そのため、 'Node'を継承する型がない場合にのみ正しいと主張することができます。 'Node'が' public'であれば 'sealed'する必要があることを意味します。また、それは別の問題ですが、主にパフォーマンス上の理由から、 'IEquatable 'も実装しています。 –

+1

@Evorlor:1. myInterface(time/resources cosuming)の比較を開始する前に、*参照平等*(インスタンスはそれ自身と同じです)をテストすることがよくあります。2. 'as'は特別に設計されていますそのような比較。この場合は 'GetType'とキャストを使わないでください。 –

+0

@Kris Vandermotten:「IEquatable 」インターフェイスの実装は*良いアイデアであると私は同意します。しかし、 'Equals'は実装(実装)ではなくノード(いくつかのグラフ?)を比較します。派生クラス 'MyNode'がポリシーを変更したい場合、' Equals'と 'GetHashCode'をオーバーライドしなければなりません。 –

関連する問題