我在一些地方读到,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>();
假设我提供的接口(interface)定义满足:
ILData : IEquatable<ILData>
要求,为什么在这种情况下我不会看到 ILData::Equals 被调用?
最佳答案
它使用 EqualityComparer<T>.Default
。由于您的类型实现了 IEquatable<T>
,实际使用的比较器将是一个名为 System.Collections.Generic.GenericEqualityComparer<T>
的内部类。 ,这将委托(delegate) GetHashCode
和Equals
请求您的object.GetHashCode
方法和IEquatable<ILData>.Equals
分别方法(null
引用除外,它返回零哈希代码/在不调用您的方法的情况下进行引用相等检查)。
有很多原因可以解释您的 Equals
方法未被命中:
- 这里有一个空序列。
- 您的断点位于
object.Equals
而不是IEquatable<ILData>.Equals
- 第二个序列仅包含
null
引用文献(这是由框架比较器检查的,因此不会输入您的引用文献)。 - 没有哈希匹配(来自
GetHashCode
),因此连接操作不需要进行完整的相等检查。发生这种情况的原因之一是您忘记重写此方法,因此只能使用object
中的默认方法。 (这是为引用平等而设计的,并且与您对平等的定义不一致)。
关于c# - LINQ 等于 - 它在幕后调用什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11417245/