2

LINQ equals (結合構文) が比較対象の型に対して IEquatable を呼び出すことをいくつかの場所で読みましたが、結合でそれが起こっていることはわかりません。

List<ILData> list1 = new List<ILData> { /* Initialized with items */ };
List<ILData> list2 = new List<ILData> { /* Initialized with items */ };

var joinItems = (
    from d1 in list1
        join d2 in list2
        on d1 equals d2
    where d1.SomeValue == "7"
    select d1).Distinct().ToList<ILData>();

以下を満たすインターフェース定義を提供したと仮定します。

ILData : IEquatable<ILData>

この場合、ILData::Equals が呼び出されないのはなぜですか?

4

2 に答える 2

5

を使用していますEqualityComparer<T>.Default。あなたの型は を実装しているのでIEquatable<T>、実際に使用される比較子は と呼ばれる内部クラスになり 、メソッドとメソッドにそれぞれSystem.Collections.Generic.GenericEqualityComparer<T>委譲GetHashCodeしてEquals要求します(参照を除いて、ゼロのハッシュコードを返す/あなたを呼び出さずに参照等価性チェックを行います)メソッド)。object.GetHashCodeIEquatable<ILData>.Equalsnull

Equalsメソッドがヒットしない理由はいくつかあります。

  1. ここでは空のシーケンスがプレイされています。
  2. あなたのブレークポイントはオンobject.EqualsではなくIEquatable<ILData>.Equals
  3. 2 番目のシーケンスにはnull参照のみが含まれます (これはフレームワークの比較機能によってチェックされるため、あなたのものには入りません)。
  4. (からの) ハッシュ一致がないGetHashCodeため、結合操作で完全な等価性チェックを行う必要はありません。これが発生する理由の 1 つは、このメソッドをオーバーライドするのを忘れたため、object(参照の等価性のために設計されており、等価性の定義と矛盾する) からのデフォルトのメソッドに固執していることです。
于 2012-07-10T16:07:21.970 に答える
0

Join 関数は、デフォルトのequality comparerを使用すると述べています。IEquatable の実装に加えて、object.GetHashCode をオーバーライドする必要があります (また、object.Equals をオーバーライドする必要があります)。

一般に、クエリ

from AA in AAAA
join BB in BBBB
on C(AA) equals D(BB)
select E(AA,BB)

に変換します

AAAA.Join(BBBB, AA => C(AA), BB => D(BB), (AA, BB) => E(AA, BB))
于 2012-07-10T16:11:12.620 に答える