[英]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
包含两个列表(顺序是不相关的,因为顺序是一组),并且每个列表具有相同的值(顺序相同)。 他们应该被认为是平等的。
我应该怎么做才能使这些HashSet
与thisList.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.