2016-04-13 15 views
5

雖然看着List.AddRange的實現,我發現奇怪的東西,我不明白。 Sourcecode, see line 727(調用的AddRange InsertRange)列表<T> .AddRange/InsertRange創建臨時數組

T[] itemsToInsert = new T[count]; 
c.CopyTo(itemsToInsert, 0); 
itemsToInsert.CopyTo(_items, index); 

爲什麼利己它集合複製到一個「臨時陣列」(itemsToInsert),然後再拷貝臨時數組實際_items陣列? 是否有任何理由背後,或者這只是複製ArrayList的源的剩餘部分,因爲同樣的事情發生在那裏。

+2

我會假設它是通過值而不是通過引用傳遞項目,以便在列表中的項目本身被修改的情況下,插入的原始項目不會被修改 –

+1

@Jdsfighter - 我看不到如何有所幫助。數組或集合的內容是值或引用。上面的代碼不會改變正在複製的內容。 –

+0

我真的不認爲它是隱藏底層數組。在我的回答中,我指出了其他可能的解釋。 – Fabjan

回答

4

我的猜測是,這是爲了隱藏內部支持數組的存在。沒有辦法獲得有意識的該數組的引用。 List類甚至不承諾有這樣一個數組。 (當然,對於性能和兼容性的原因它總是會以與陣列實現。)

有人可能傳遞一個特製ICollection<T>可以記住它通過陣列。現在呼叫者可能會混淆List的內部數組,並根據List內部結構開始。

將其與MemoryStream對比,該文件有一個文檔化的訪問內部緩衝區的方法(並用它拍攝自己):GetBuffer()

+0

如果這是真正的原因,那麼我真的不明白這一點:如果他們想要弄亂事情,也可以使用反射來尋找私有數組字段。 –

+0

使用反射,你可以撬開任何東西,但這很難,在實踐中更少發生。這似乎可以防止意外或粗心的API濫用。調用代碼總是開始依賴於現在發生的不變量,但不能保證。越難,這將是更罕見的。 – usr

+1

我想說,製作一個記憶陣列的集合,意圖與內部混淆並不是那麼普遍。真正的意圖是相同的,而不是我認爲值得在通用庫中保護的東西。編輯:我知道,這確實可以防止某些意外誤用。畢竟給定了多少List,這並沒有那麼牽強。 –