C# 如何使用自定义IEqualityComparer来比较集合?

C# 如何使用自定义IEqualityComparer来比较集合?,c#,C#,我正在尝试使用自定义IEqualityComparer测试列表相等性,但我的实现不起作用 var expected = new List<Space> { new Space(7, 7, 'a'), new Space(7, 8, 'b') }; var result = new List<Space> { new Space(7, 7, 'a'), new Space(7, 8, 'b') }; //These asserts pass Assert.

我正在尝试使用自定义IEqualityComparer测试列表相等性,但我的实现不起作用

var expected = new List<Space> { new Space(7, 7, 'a'), new Space(7, 8, 'b') };
var result = new List<Space> { new Space(7, 7, 'a'), new Space(7, 8, 'b') };

        //These asserts pass
Assert.That(SpaceTileEqualityComparer.Instance.Equals(expected[0], result[0]));
Assert.That(SpaceTileEqualityComparer.Instance.Equals(expected[1], result[1]));
Assert.That(expected.Count() == result.Count());
Assert.That(result.Except(expected, SpaceCoordsEqualityComparer.Instance).Count(), Is.EqualTo(0));

        //This assert fails
Assert.That(result.Except(expected, SpaceTileEqualityComparer.Instance).Count(), Is.EqualTo(0));
var expected=newlist{newspace(7,7,'a')、newspace(7,8,'b');
var result=new List{new Space(7,7,'a')、new Space(7,8,'b')};
//这些断言是不成立的
Assert.That(spaceTileQualityComparer.Instance.Equals(预期为[0],结果为[0]));
Assert.That(spaceTileQualityComparer.Instance.Equals(预期为[1],结果为[1]));
Assert.That(预期的.Count()==result.Count());
Assert.That(result.Except(应为SpaceCoordsEqualityComparer.Instance).Count(),为.EqualTo(0));
//此断言失败
Assert.That(result.Except(应为SpaceTileEqualityComparer.Instance).Count(),为.EqualTo(0));
如您所见,我有两个列表,每个列表由两个空间类型对象组成。我有两个IEqualityCompaper的自定义实现:SpaceCoordsEqualityComparer检查空间对象中的前两个值是否相等。SpaceTileQualityComparer检查三个值是否相等

前两个断言是为了证明SpaceTileQualityComparer正在做它的工作。每个列表中的每个元素都被视为与其对应的元素。第三个断言只是为了让我自己确信,列表中没有任何奇怪的事情发生,也没有其他元素潜入其中。第四个断言是我最初测试列表平等性的方式。我正在创建一个新列表,方法是使用Except()方法从第一个列表中减去列表之间的公共元素,然后断言新列表的计数为0。这也适用于自定义比较器,它只测试空间对象中的前两个值。但是,当我使用检查三个元素的自定义比较器时,Except方法不会减去任何元素并返回计数2的列表

所以,从我所知道的,自定义比较器可以工作。名单是相等的。将Except()与自定义比较器一起使用可创建无长度的新列表。但当我把所有这些元素放在一起时,有些地方出了问题

以下是两个比较器:

public class SpaceCoordsEqualityComparer : EqualityComparer<Space>
{
    private static readonly SpaceCoordsEqualityComparer _instance = new SpaceCoordsEqualityComparer();

    public static SpaceCoordsEqualityComparer Instance { get { return _instance; } }

    public override bool Equals(Space a, Space b)
    {
        if (a == null && b == null)
            return true;
        if (a == null || b == null)
            return false;

        return a.GetCoords().Equals(b.GetCoords());
    }

    public override int GetHashCode(Space obj)
    {
        return obj.GetX().GetHashCode() ^ obj.GetY().GetHashCode();
    }
}
public class SpaceTileEqualityComparer : EqualityComparer<Space>
{
    private static readonly SpaceTileEqualityComparer _instance = new SpaceTileEqualityComparer();

    public static SpaceTileEqualityComparer Instance { get { return _instance; } }

    public override bool Equals(Space a, Space b)
    {
        if (a == null && b == null)
            return true;
        if (a == null || b == null)
            return false;

        return (a.GetCoords().Equals(b.GetCoords())) && (a.GetTileLetter() == b.GetTileLetter());
    }

    public override int GetHashCode(Space obj)
    {
        return obj.GetCoords().GetHashCode() ^ obj.GetTile().GetHashCode();
    }
}
公共类SpaceCoordsEqualityComparer:EqualityComparer
{
私有静态只读SpaceCoordsEqualityComparer _实例=新SpaceCoordsEqualityComparer();
公共静态SpaceCoordsEqualityComparer实例{get{return}
公共覆盖布尔等于(空间a、空间b)
{
如果(a==null&&b==null)
返回true;
如果(a==null | | b==null)
返回false;
返回a.GetCoords().Equals(b.GetCoords());
}
公共覆盖int GetHashCode(空格obj)
{
返回obj.GetX().GetHashCode()^obj.GetY().GetHashCode();
}
}
公共类SpaceTileQualityComparer:EqualityComparer
{
私有静态只读SpaceTileEqualityComparer _实例=新SpaceTileEqualityComparer();
公共静态SpaceTileQualityComparer实例{get{return}
公共覆盖布尔等于(空间a、空间b)
{
如果(a==null&&b==null)
返回true;
如果(a==null | | b==null)
返回false;
返回(a.GetCoords().Equals(b.GetCoords())&&(a.GetTileLetter()==b.GetTileLetter());
}
公共覆盖int GetHashCode(空格obj)
{
返回obj.GetCoords().GetHashCode()^obj.GetTile().GetHashCode();
}
}

对于未来的任何人,我都解决了这个bug。事实证明,我在第二个自定义比较器中以不正确的方式重写了GetHashCode方法。在修复该代码后,我使用自定义IEqualityComparer with List.Except的实现成功了。您可能希望将此作为答案并回答您自己的问题。对于将来的任何人,我都解决了该错误。事实证明,我在第二个自定义比较器中以不正确的方式重写了GetHashCode方法。修复该代码后,我使用自定义IEqualityComparer with List.Except的实现成功了。您可能希望将其放入答案中,然后回答自己的问题。