LINQ等于 - 它涵盖了什么?

时间:2012-07-10 15:57:05

标签: c# .net linq .net-3.5

我在一些地方读到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被调用?

2 个答案:

答案 0 :(得分:5)

它使用EqualityComparer<T>.Default。由于您的类型实现了IEquatable<T>,因此使用的实际比较器将是一个名为System.Collections.Generic.GenericEqualityComparer<T>的内部类,它将GetHashCodeEquals请求委托给您的object.GetHashCode方法,分别为IEquatable<ILData>.Equals个方法(null引用除外,它返回零哈希代码/进行引用相等性检查而不调用方法)。

有很多原因可以解释您的Equals方法没有被点击:

  1. 这里有一个空序列。
  2. 您的断点位于object.Equals而不是IEquatable<ILData>.Equals
  3. 第二个序列只包含null引用(由框架比较器检查,因此不会输入您的引用)。
  4. 没有哈希匹配(来自GetHashCode),因此连接操作永远不需要进行完全相等检查。可能发生这种情况的一个原因是您忘记覆盖此方法,因此无法使用object中的默认方法(其设计用于引用相等,并且与您的相等定义不一致)。

答案 1 :(得分:0)

Join function表示它使用default 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))