我有一个不变的值对象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/

10-11 02:14