我正在从事Active Directory同步项目,并且试图将AD中的用户列表与数据库中存储的用户列表进行比较。我已经实现了一个自定义的UserPrincipal
(我创造性地称为NetworkUserPrincipal
)来公开一些我们在入职时需要设置的属性。 NetworkUserPrincipal
也实现IEqualityComparer<NetworkUserPrincipal>
。
我还在进行小样本量的单元测试,并且正在尝试制定一个流程来跳过信息未更改的每个人。这是我的测试:
// a static list of two users
List<NetworkUserPrincipal> expected = JobTestData.InternalActiveDirectoryData.SynchronizedUsers
// returns only one user.
List<NetworkUserPrincipal> actual = _activeDirectoryUsers.Intersect(_databaseUsers).ToList(); // returns only one user.
Assert.IsTrue(expected.All(_databaseUsers.Contains)); // true
Assert.IsTrue(expected.All(_activeDirectoryUsers.Contains)); // true
Assert.IsTrue(expected.SequenceEqual(actual)); // false
但是,如果将
_activeDirectoryUsers.Intersect(_databaseUsers).ToList();
更改为_activeDirectoryUsers.Where(_databaseUsers.Contains).ToList();
,则我的最终测试通过。在调试单元测试时,我在Equals覆盖函数中放置了一个断点,并且在
Intersect
场景中该断点仅被调用一次。这是怎么回事?
最佳答案
您需要正确实现GetHashCode()
才能使用Intersect
。不知道为什么,但是没有它确实有问题。
Fiddle without GetHashCode()
Fiddle with GetHashCode()
似乎GetHashCode
的任何实现(甚至是不正确的实现),但不是默认的对象一。
编辑:正如@ScottChamberlain在评论中解释的那样,不是任何非正确的实现都可以,它确实需要一个正确的实现(每个相等的对象都返回相等的哈希码)。它不需要高效,只需正确即可。
关于c# - 为什么我的List.Intersect返回的结果与Where(List.Contains)不同?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35729558/