我有一个不变的值对象IPathwayModule,其值由以下项定义:
(int)块;
(实体)模块,由(字符串)ModuleId标识;
(枚举)状态;和
(实体)类,由(字符串)ClassId标识-可以为null。
这是我当前的IEqualityComparer实现,似乎可以在一些单元测试中使用。但是,我认为我不太了解自己做得如何,是否知道自己做得对。先前的实现有时会在重复测试运行中失败。
private class StandardPathwayModuleComparer : IEqualityComparer<IPathwayModule>
{
public bool Equals(IPathwayModule x, IPathwayModule y)
{
int hx = GetHashCode(x);
int hy = GetHashCode(y);
return hx == hy;
}
public int GetHashCode(IPathwayModule obj)
{
int h;
if (obj.Class != null)
{
h = obj.Block.GetHashCode() + obj.Module.ModuleId.GetHashCode() + obj.Status.GetHashCode() + obj.Class.ClassId.GetHashCode();
}
else
{
h = obj.Block.GetHashCode() + obj.Module.ModuleId.GetHashCode() + obj.Status.GetHashCode() + "NOCLASS".GetHashCode();
}
return h;
}
}
IPathwayModule绝对是不可变的,具有相同值的不同实例应相等,并产生相同的HashCode,因为它们被用作HashSets中的项目。
我想我的问题是:
在这种情况下,我可以正确使用接口吗?
在某些情况下,我可能看不到预期的行为?
有什么方法可以提高鲁棒性,性能?
有没有我没有遵循的良好做法?
最佳答案
不要对Hash函数的结果做等于,它太脆弱了。而是对每个字段进行字段值比较。就像是:
return x != null && y != null && x.Name.Equals(y.Name) && x.Type.Equals(y.Type) ...
另外,哈希函数的结果并不真正适合添加。尝试改用
^
运算符。return obj.Name.GetHashCode() ^ obj.Type.GetHashCode() ...
您不需要在GetHashCode中进行null检查。如果该值为null,那么您将遇到更大的问题,试图从无法控制的事物中恢复将毫无用处...
关于c# - IEqualityComparer用于值对象,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1565667/