2012-11-17 86 views
3

在審查一個應用程序的代碼時,我發現它假定Dictionary.Values的順序與添加到集合中的元素相同。是否保證Dictionary.Values按照添加的順序返回元素?

我寫的應用程序進行測試,如果這是真的:

using System; 
using System.Collections.Generic; 

namespace Test 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      Dictionary<string, int> values = new Dictionary<string, int>(); 

      values.Add("apple2", 2); 
      values.Add("apple3", 3); 
      values.Add("apple4", 4); 
      values.Add("apple5", 5); 
      values.Add("apple6", 6); 
      values.Add("apple1", 1); 

      var list = new List<int>(values.Values); 

      for (int i = 0; i < list.Count; i++) 
      { 
       Console.WriteLine(list[i]); 
      } 

     } 
    } 
} 

和輸出是:

所有的
2 
3 
4 
5 
6 
1 

首先,我不知道這怎麼可能。不是字典應該使用無序樹或類似的東西?

此外MSDN指出:

的值的順序在Dictionary<TKey, TValue>.ValueCollection是不確定的,但它是相同的順序在Dictionary<TKey, TValue>.KeyCollection所述相關聯的密鑰由密鑰屬性返回。

那麼,爲什麼MSDN告訴「訂單未指定」,但實施恰巧保持秩序?我是否正確,我最好不要依賴這個事實?

+2

它說,'ValueCollection'是在同一順序爲'KeyCollection' ...但你不知道爲了什麼'KeyCollection'是在(即你不知道這是否是相同的順序如何插入)。 換句話說,如果你插入: (1,a),(2,b),(3,c) 規範只是說如果'KeyCollection'返回(2,3,1)然後'ValueCollection'將返回(b,c,a) – rliu

回答

5

我是否正確,我最好不要依賴這個事實?

絕對。僅僅因爲有時候是它保留了順序並不意味着它將在未來的實現中,或者實際上它現在可以在所有情況下都能實現。

當調整內部數據結構的大小或刪除項目時,順序可能會更改。

例如,如果您構建列表之前添加以下代碼:

values.Remove("apple4"); 
values.Add("jon", 10); 

在我的箱子,我看到了價值10從哪裏來4是以前......即使它後添加對於5,6和1的條目。

你應該絕對,絕對是不依賴於排序。

+0

感謝喬恩。我花時間瞭解了這些代碼是如何工作的,然後編寫了一個測試,因此畢竟我決定人們不能編寫這樣的代碼(爲什麼有人會決定保留這個訂單?),我決定了這可能是我錯過了什麼...... – javapowered

+0

@javapowered:我不太確定我是否正確地解析了你的評論,但它聽起來像你沒有錯過任何東西 - 你真的,真的不應該依賴於排序,並且如果有代碼,你應該修復它。 –

2

您正在獲取值的順序可能是由於您的數據看起來有序。更改混合訂單的元素並添加刪除其訂單將被更改的元素。你不能依賴訂單。

相關問題