繁体   English   中英

HashSet上的C#SetEquals <List<float> &gt;当预期为真时为假

[英]C# SetEquals on HashSet<List<float>> is false when expected true

执行某些C#(。NET 4.6,Visual Studio 2015 Professional)的Python开发人员在这里工作。 我正在尝试检查两个HashSet是否相等。

我有两个HashSet<List<float>> ,我正在尝试使用它们进行比较

thisList.SetEquals(otherList);

但是,这对我的数据返回false 使用MSDN HashSet的示例的示例确实可以正常工作。 但是,在示例中,它们使用HashSet<int>而我使用HashSet<List<float>>

由于找不到在Visual Studio中将HashSet内容打印到“即时窗口”中的方法( ToString返回"System.Collections.Generic.HashSet1[System.Collections.Generic.List1[System.Single]]" )),因此我使用了Json。 NET JsonConvert.SerializeObject(thisList); 将数据转储到磁盘上的.json文件中。

两个文件(每个HashSet内容的每个文件是:

[[10.0,15.0],[20.0,25.0]][[10.0,15.0],[20.0,25.0]]

调试时在Visual Studio中检查HashSet ,如下所示:

-       thisList    Count = 2   System.Collections.Generic.HashSet<System.Collections.Generic.List<float>>
-       [0] Count = 2   System.Collections.Generic.List<float>
        [0] 10  float
        [1] 15  float
+       Raw View        
-       [1] Count = 2   System.Collections.Generic.List<float>
        [0] 20  float
        [1] 25  float
+       Raw View        
+       Raw View        
-       otherList   Count = 2   System.Collections.Generic.HashSet<System.Collections.Generic.List<float>>
-       [0] Count = 2   System.Collections.Generic.List<float>
        [0] 20  float
        [1] 25  float
+       Raw View        
-       [1] Count = 2   System.Collections.Generic.List<float>
        [0] 10  float
        [1] 15  float
+       Raw View        
+       Raw View        

每个HashSet包含两个列表(顺序是不相关的,因为顺序是一组),并且每个列表具有相同的值(顺序相同)。 他们应该被认为是平等的。

我应该怎么做才能使这些HashSetthisList.SetEquals(otherList);相等thisList.SetEquals(otherList);

编辑:

在每个float上打印coord.ToString("G17")

10
15
20
25
20
25
10
15

因为您在HashSet中使用List,所以它将两个列表作为参考进行比较,而不是考虑Lists中的值。

不要使用List来表示X和Y,而应使用Vector2或Point类。 这或多或少是该结构的外观:

public struct Point
{
    public double X {get; }
    public double Y { get; }

    public Point(double x, double y)
    {
        X = x;
        Y = y;
    }

    public bool Equals(Point other)
    {
        return X.Equals(other.X) && Y.Equals(other.Y);
    }

    public override bool Equals(object obj)
    {
        if (ReferenceEquals(null, obj)) return false;
        return obj is Point && Equals((Point) obj);
    }

    public override int GetHashCode()
    {
        unchecked
        {
            return (X.GetHashCode() * 397) ^ Y.GetHashCode();
        }
    }
}

您试图检查HashSet<List<float>>与另一个对象HashSet<List<float>>相等操作。 这里的问题是为什么它返回false

现在,在我们谈论HashSet<List<float>> ,让我们来谈谈,如果我检查等于(使用下面代码) List<float>与另一个对象List<float> ,那么这将是输出?

    List<float> list = new List<float>() { 10.0f, 15.0f};
    List<float> anotherList = new List<float>() { 10.0f, 15.0f};

    Console.WriteLine(list.Equals(anotherList));

此输出将是

由于在这里Equals比较对象的引用(不相等)。

现在解决您的问题

在初始化HashSet时,应提供一个EqualityComparer ,它应根据需要检查类型T。

    HashSet<List<float>> HashSet1 = new HashSet<List<float>>(new FloatListComparer());
    anotherHashSet1.Add(list);

    HashSet<List<float>> anotherHashSet2 = new HashSet<List<float>>();
    anotherHashSet2.Add(anotherList);

    Console.WriteLine(anotherHashSet1.SetEquals(anotherHashSet2));

上面代码的输出是

真正

我在这里编写的EqualityComparer如下所示。

public class FloatListComparer : EqualityComparer<List<float>>
{
    public override bool Equals(List<float> list1, List<float> list2)
    {
        return list1.SequenceEqual(list2);
    }

    public override int GetHashCode(List<float> s)
    {
        return base.GetHashCode();
    }
}

现在的问题是,为什么SetEquals无法正常工作

如果在此处检查SetEquals的实现,则将发现它调用T的默认比较器,该比较器基于检查对象的引用而工作。 通过提供比较器, SetEquals使用指定的比较器。

这里检查现场提琴手。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM