.Except(LINQ)为什么不能正确比较事物? (使用IEquatable) [英] Why isn't .Except (LINQ) comparing things properly? (using IEquatable)

查看:72
本文介绍了.Except(LINQ)为什么不能正确比较事物? (使用IEquatable)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有自己的引用类型对象的两个集合,我为它们编写了自己的IEquatable.Equals方法,并且希望能够在它们上使用LINQ方法.

I have two collections of my own reference-type objects that I wrote my own IEquatable.Equals method for, and I want to be able to use LINQ methods on them.

所以

List<CandyType> candy = dataSource.GetListOfCandy();
List<CandyType> lollyPops = dataSource.GetListOfLollyPops();
var candyOtherThanLollyPops = candy.Except( lollyPops );

根据.Except的文档,未传递IEqualityComparer会导致EqualityComparer.Default用于比较对象.默认比较器的文档是这样的:

According to the documentation of .Except, not passing an IEqualityComparer should result in EqualityComparer.Default being used to compare objects. And the documentation for the Default comparer is this:

"Default属性检查类型T是否实现System.IEquatable通用接口,如果是,则返回使用该实现的EqualityComparer.否则,它返回使用T提供的Object.Equals和Object.GetHashCode的重写的EqualityComparer. "

"The Default property checks whether type T implements the System.IEquatable generic interface and if so returns an EqualityComparer that uses that implementation. Otherwise it returns an EqualityComparer that uses the overrides of Object.Equals and Object.GetHashCode provided by T."

因此,因为我为我的对象实现了IEquatable,所以它应该使用它并起作用.但是,事实并非如此.直到我重写GetHashCode,它才起作用.实际上,如果设置断点,则IEquatable.Equals方法将永远不会执行.这使我认为根据它的文档,它与计划B一起使用.我知道,无论如何,重写GetHashCode是个好主意,而且我可以使它正常工作,但是令我感到沮丧的是,它的行为方式与它自己的文档所述不符.

So, because I implement IEquatable for my object, it should use that and work. But, it doesn't. It doesn't work until I override GetHashCode. In fact, if I set a break point, my IEquatable.Equals method never gets executed. This makes me think that it's going with plan B according to its documentation. I understand that overriding GetHashCode is a good idea, anyway, and I can get this working, but I am upset that it is behaving in a way that isn't in line with what its own documentation stated.

为什么它没有按照它所说的去做?谢谢.

Why isn't it doing what it said it would? Thank you.

推荐答案

经调查,事实证明事情并没有我想象的那么糟糕.基本上,如果一切都正确执行(GetHashCode等),则说明文件正确,并且行为正确.但是,如果您尝试自己单独执行类似实现IEquatable的操作,则您的Equals方法将永远不会被调用(这似乎是由于GetHashCode的实现不正确).因此,尽管该文档在技术上是错误的,但仅在您永远都不想做的情况下才是错误的(如果此调查教给我任何东西,那就是IEquatable是您应实现的整套方法的一部分原子地(不幸的是,按照惯例,而不是按规则).

After investigation, it turns out things aren't quite as bad as I thought. Basically, when everything is implemented properly (GetHashCode, etc.) the documentation is correct, and the behavior is correct. But, if you try to do something like implement IEquatable all by itself, then your Equals method will never get called (this seems to be due to GetHashCode not being implemented properly). So, while the documentation is technically wrong, it's only wrong in a fringe situation that you'd never ever want to do (if this investigation has taught me anything, it's that IEquatable is part of a whole set of methods you should implement atomically (by convention, not by rule, unfortunately)).

关于此的良好来源是:

  • Is there a complete IEquatable implementation reference?
  • MSDN Documentation: IEquatable<T>.Equals(T) Method
  • SYSK 158: IComparable<T> vs. IEquatable<T>

这篇关于.Except(LINQ)为什么不能正确比较事物? (使用IEquatable)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆