簡體   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