2012-02-22 10 views
0

を使用して、最後のパラメータとしてLinq Joinメソッドを渡すときにEqualsメソッドを使用していないため、GetHashCodeを使用してアイテムを比較しています。LINQ結合がEqualityComparerからのEqualsを使用していない場合、代わりに

代わりにEqualsを使用することはできますか?

 var ss = new string[] { "aa", "bb", "cc" }; 
     var zz = new string[] { "aa", "zz", "cc" }; 

     var res = ss 
      .Join(zz, 
       o => o, 
       i => i, 
       (i, o) => i + o, 
       new GenericEqualityComparer<String>((x,y) => x == y)) 
      .ToList(); 
+0

それは_never_または_常にalways_が 'Equals'を使用していないことを意味しますか? –

答えて

1

IEqualityComparer<T>がオブジェクトと比較されると、最初にハッシュコードが比較されます。等しい場合にのみEqualsメソッドを使用して比較を絞り込みます。あなたの場合、少なくともEqualsを2回押してください。

EqualityComparerは私がLinqpadに少しのコードスニペットを作ったん何を実証するために:

void Main() 
{ 
    var ss = new string[] { "aa1", "bb1", "cc1" }; 
    var zz = new string[] { "aa2", "aa3", "zz2", "cc2" }; 

    var res = ss.Join(zz, o => o, i => i, (i, o) => i + o, 
     new SubstringComparer()).ToList(); 
} 

public class SubstringComparer : IEqualityComparer<string> 
{ 
    public bool Equals(string left, string right) 
    { 
     string.Format("{0} - {1}", left, right).Dump(); 
     return left.Substring(0,2) == right.Substring(0,2); 
    } 

    public int GetHashCode(string value) 
    { 
     value.Dump(); 
     return value.Substring(0,2).GetHashCode(); 
    } 
} 

彼らの最初の2つの文字が等しいのであれば、文字列が等しいです。出力は次のとおり

AA2
AA3
AA2 - CC1

から
BB1
CC1
CC2 AA1 -
ZZ2
CC2
AA1
AA2 AA3そして、リスト:あなたが第一、第二のリストは、その後、比較(ちなみに、多分ハッシュコードがキャッシュされている理由を、私はよく分からない)とされていることが分かり

aa1aa2
aa1aa3
cc1cc2

ペア。

だから、何とかいつも私がバグであるべきだと思うユニークなハッシュコードを生成するとき、あなたのGenericEqualityComparer決してヒットEqualsが必ずしもでない場合は、Equalsを使用してください。ここで説明します。そして、比較者をにする場合は、常にを使用してください。Equalsを使用する場合は、常に同じハッシュコードを返さなければなりません(これはもちろん非効率です)。

0

https://stackoverflow.com/a/3719802/136967

非常に良い説明があります。基本的に、比較はEquals()を使用して行われますが、GetHashCode()は処理を行う際にLinqコードによって使用され、正しく実装されていないと奇妙な回答が返されます。

hth、
アラン。

関連する問題