我正在从事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/

10-10 19:16