Sam*_*les 5 c# linq set hashcode
我想知道是否有人对此问题有任何建议.
我使用带有自定义IEqualityComparer的intersect和except(Linq)来查询设置差异并设置两个ISyncableUsers序列的交集.
public interface ISyncableUser
{
string Guid { get; }
string UserPrincipalName { get; }
}
Run Code Online (Sandbox Code Playgroud)
两个ISyncableUsers是否相等的逻辑是有条件的.条件围绕两个属性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);
}
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是实现GetHashCode,以便尊重上面表示的上述条件相等.我能够获得交叉的唯一方法是除了调用按预期工作之外,简单总是从GetHashCode()返回相同的值,强制调用Equals.
public int GetHashCode(ISyncableUser obj)
{
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这可行,但性能损失是巨大的,如预期的那样.(我已经用非条件相等测试了这个.有两个包含50000个对象的集合,一个正确的哈希码实现允许执行拦截,除了大约40ms.总是返回0的哈希码实现大约需要144000ms(是的,2.4分钟!) )
那么,我将如何在上面的场景中实现GetHashCode()呢?
任何想法都会受到欢迎!
如果我没看错的话,你的平等关系是不传递的。想象一下以下三个ISyncableUser
:
A { Guid: "1", UserPrincipalName: "2" }
B { Guid: "2", UserPrincipalName: "2" }
C { Guid: "2", UserPrincipalName: "1" }
Run Code Online (Sandbox Code Playgroud)
A == B
因为他们有相同的UserPrincipalName
B == C
因为他们有相同的Guid
A != C
因为他们也不分享。从规格来看,
Equals方法具有自反性、对称性和传递性。也就是说,如果用于将对象与其自身进行比较,则返回true ;对于两个对象为真
x
,并且y
如果对于和为真;且对于两个对象为真,并且如果对于和为真,并且对于和也为真。y
x
x
z
x
y
y
z
如果你的等式关系不一致,你就无法实现支持它的哈希码。
从另一个角度来看:您本质上是在寻找三个功能:
G
将 GUID 映射到整数(如果您知道 GUID 但 UPN 为空)U
将 UPN 映射到整数(如果您知道 UPN 但 GUID 为空)P
将 (guid, upn) 对映射到整数(如果您两者都知道)这样G(g) == U(u) == P(g, u)
对于所有g
和u
. g
这只有在你完全忽略的情况下才有可能u
。
归档时间: |
|
查看次数: |
4338 次 |
最近记录: |