【发布时间】:2012-10-23 01:15:35
【问题描述】:
我想知道是否有人对这个问题有任何建议。
我将 intersect 和 except (Linq) 与自定义 IEqualityComparer 一起使用,以查询 ISyncableUser 的两个序列的设置差异和设置交集。
public interface ISyncableUser
{
string Guid { get; }
string UserPrincipalName { get; }
}
两个 ISyncableUser 是否相等背后的逻辑是有条件的。条件围绕 Guid 和 UserPrincipalName 这两个属性中的任何一个是否具有值。解释这种逻辑的最好方法是使用代码。下面是我的客户 IEqualityComparer 的 Equals 方法的实现。
public bool Equals(ISyncableUser userA, ISyncableUser userB)
{
if (userA == null && userB == null)
{
return true;
}
if (userA == null)
{
return false;
}
if (userB == null)
{
return false;
}
if ((!string.IsNullOrWhiteSpace(userA.Guid) && !string.IsNullOrWhiteSpace(userB.Guid)) &&
userA.Guid == userB.Guid)
{
return true;
}
if (UsersHaveUpn(userA, userB))
{
if (userB.UserPrincipalName.Equals(userA.UserPrincipalName, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
}
return false;
}
private bool UsersHaveUpn(ISyncableUser userA, ISyncableUser userB)
{
return !string.IsNullOrWhiteSpace(userA.UserPrincipalName)
&& !string.IsNullOrWhiteSpace(userB.UserPrincipalName);
}
我遇到的问题是实现 GetHashCode 以便尊重上面表示的上述条件相等。我能够让 intersect 和 except 调用按预期工作的唯一方法是简单地始终从 GetHashCode() 返回相同的值,从而强制调用 Equals。
public int GetHashCode(ISyncableUser obj)
{
return 0;
}
这可行,但正如预期的那样,性能损失很大。 (我已经用非条件相等性对此进行了测试。对于两个包含 50000 个对象的集合,正确的哈希码实现允许在大约 40 毫秒内执行拦截和除外。始终返回 0 的哈希码实现大约需要 144000 毫秒(是的,2.4 分钟!) )
那么,我将如何在上述场景中实现 GetHashCode()?
欢迎提出任何想法!
【问题讨论】:
-
是否有意使用 string.IsNullOrEmpty 而不是 string.IsNullOrWhiteSpace 检查 userB.UserPrincipalName,就像对 userA.UserPrincipalName 一样?检查应该相同才能有正确的 Equals 方法。
-
不,抱歉,我直接输入了 SO,那是我的错误。我现在已经更正了。