2014-10-05 43 views
1

我創建了一個程序,在其中我有INT陣列的隊列:當在隊列中使用Contains時,控制檯返回False。爲什麼?

Queue<int[]> Test = new Queue<int[]>(); 

鑑於陣列,我想要查詢的陣列是否在隊列內。

我目前使用的命名空間是:System,System.Collections和System.Collections.Generic。

我想是這樣的:

Queue<int[]> Test = new Queue<int[]>(); 

Test.Enqueue(new int[] { 20, 20 }); 

Console.WriteLine(Test.Contains(new int[] { 20, 20 })); // Is the array {20,20} inside the queue? 

在這段代碼中,在我看來,控制檯會輸出「真」,因爲我加入了數組{20,20}到隊列中,而現在我正在使用Contains方法進行檢查。

但是當我運行代碼 - 控制檯輸出false。

我有兩個問題: 這是爲什麼發生?我該如何解決這個問題?

+0

比較適用於引用,您需要創建相等比較器或循環遍歷每個數組並調用SequenceEqual並傳遞該新數組以進行比較。 – terrybozzio 2014-10-05 17:16:34

回答

3

因爲數組是引用類型的比較將基於引用。即使內容相同,你的陣列也有不同的參考。這就是爲什麼你得到false

爲了解決這個問題,你可以實現一個自定義比較,也可以使用LINQ方法,例如

bool arrayExists = Test.Any(x => x.SequenceEqual(new[] { 20, 20 })); 
+0

在正確的軌道上,但會爲每個測試分配一個新的陣列。 – 2014-10-05 17:12:55

+0

是的,它可以通過在查詢中創建數組來避免。 – 2014-10-05 17:15:05

1

Contains()使用該類型的默認比較器。對於數組,它比較數組引用,而不是內容。您將需要創建一個自定義的相等比較器。

像這樣:

class ArrayComparer : IEqualityComparer<int[]> 
{ 
    public bool Equals(int[] x, int[] y) 
    { 
     return x.SequenceEqual(y); 
    } 

    public int GetHashCode(int[] obj) 
    { 
     int h = 0; 

     foreach (int item in obj) 
     { 
      h = (h << 5) + 3 + h^item.GetHashCode(); 
     } 

     return h; 
    } 
} 

Test.Contains(new int[] { 20, 20 }, new ArrayComparer()) 
0

數組由默認情況下,沒有內容的參考比較。解決這個問題的一種方法是存儲列表而不是數組,這將比較內容。您可以在添加到隊列之前將您的陣列轉換爲列表,如果這很重要,可以在將它們取出後再次將其轉換回列表。

相關問題