2016-03-20 11 views
0

私は親オブジェクトの2番目の子オブジェクトのリストを2つ持っています。子オブジェクトには、親クラスのプロパティと比較したい追加のプロパティがあります。ここ特定の値で親のリストを子のリストと比較する

public class Parent 
{ 
    public int X { get; set; } 
} 

public class Child : Parent 
{ 
    public int Y { get; set; } 
} 

public class ClassXCompare : IEqualityComparer<Parent> 
{ 
    public bool Equals(Parent x, Parent y) 
    { 
     var child = (Child)y; 
     return x.X == child.Y; 
    } 

    public int GetHashCode(Parent parent) 
    { 
     int parentXhash = parent.X.GetHashCode(); 
     // Calculate the hash code for the product. 
     return parentXhash ; 
    } 
} 

、今私は、次のテストならば、それは常に

var parentList= new List<Parent> 
     { 
      new Parent {X = 5}, 
      new Parent {X = 6} 
     }; 
     var childList= new List<Child> 
     { 
      new Child {Y = 5}, 
      new Child {Y = 6} 
     }; 
     var compare = new ClassXCompare(); 
     var diff = parentList.Except(childList, compare); 
     Assert.IsTrue(!diff.Any()); // Fail ??? 

に失敗し、私は私の問題はGetHashCodeメソッド機能

どれに位置していると思うの例でありますどのようにこれを解決するアイデア?

(これは、問題の バージョンを簡素化されたアプリケーションの設計を無視してください)

+0

'y'は常に' var child =(Child)y; 'の' Child'になると確信していますか?いずれにしても、「常に失敗する」(例外、間違った結果など)という意味を正確に明確にしてください。 –

+0

はいyは常に子ですが、例外はありません。** var diff = parentList.Except(childList、compare); **空を返しますが、 – Maro

答えて

2

これは本当に恐ろしいデザインです。コンターの特定の型にキャストする必要があるため、問題が終了することはありません。

ただし、以下のコードは合格します。キャストの異なる方法、nullチェック、およびexcept行のリストの順序に注意してください。

問題は、ChildインスタンスがXを設定せず、Exceptメソッドが値をEqualsに渡す順序が、「x」が「y」ではない子であることを意味しました。

これは「うまくいく」かもしれませんが、デザインを真剣に考え直すべきです。

public class Parent 
{ 
    public int X { get; set; } 
} 

public class Child : Parent 
{ 
    public int Y { get; set; } 
} 

public class ClassXCompare : IEqualityComparer<Parent> 
{ 
    public bool Equals(Parent x, Parent y) 
    { 
     var child = y as Child; 

     return child != null && x.X == child.Y; 
    } 

    public int GetHashCode(Parent parent) 
    { 
     var c = parent as Child; 
     if (c == null) 
      return parent.X.GetHashCode(); 
     else 
      return c.Y.GetHashCode(); 
    } 
} 

[TestClass] 
public class UnitTest1 
{ 
    [TestMethod] 
    public void TestMethod1() 
    { 
     var parentList = new List<Parent> 
      { 
        new Parent {X = 5}, 
        new Parent {X = 6} 
      }; 
     var childList = new List<Child> 
      { 
        new Child {Y = 5}, 
        new Child {Y = 6} 
      }; 
     var compare = new ClassXCompare(); 
     var diff = childList.Except(parentList, compare); 
     Assert.IsTrue(!diff.Any()); // Fail ???  
    } 
} 
+0

はありません。私の質問に書かれていることは、私はデザインを変更する権限がないということです。だから私はこれを実装する必要があります:-(おかげで再度私はテストを行うでしょう – Maro

+0

十分に公正で、常にそうではありません:) – AndyPook

+0

おかげでアンディ、私はあなたの答えをマークしました。 2倍を比較するが、私は常に偽になるが、これは別の質問である – Maro

0

セット/辞書内のequalsだけGetHashCodeメソッドは、両方の項目に同じ値を返す場合にのみ呼び出されます - 参照しますGeneral advice and guidelines on how to properly override object.GetHashCode()。あなたが複数の子クラスを処理する必要があれば、それは非常に拡張可能ではありませんが

public class ClassXCompare : IEqualityComparer<Parent> 
{ 
    public bool Equals(Parent x, Parent y) 
    { 
     var child = (Child)y; 
     return x.X == child.Y; 
    } 

    public int GetHashCode(Parent parent) 
    { 
     var child = parent as Child; 
     return child == null ? 
      parent.X : child.Y. 
    } 
} 

:それを修正する最も簡単な方法は、子の値が利用可能な場合HashCodeを計算するために使用され、このようなものを、使用することです。

カスタムgeneric IEqualityComparerというカスタム以外の複数の子クラスを扱う簡単な方法があるのか​​どうかはわかりませんが、ちょっと短くするだけです。

P.S.また、2番目のパラメータが常にChildになることは確かではありません(この特定の使用法の現在の実装は適切な方法で動作するようですが、疑問があります)。パラメータの順序。

関連する問題