2013-09-25 32 views
0

我有一些使用反向擴展方法的代碼。.NET ToList是否保證始終返回一個新對象?

爲了確保它不會顛倒原始列表,原始程序員使用GetRange創建了一個新列表。

dim a = New List(of Thing) 
... fill in a 
dim b = a.GetRange(0, a.count) 
b.reverse() 

推測GetRange保證始終創建一個新的對象。這是否也適用於ToList?

然後,我可以寫:

dim a = New List(of Thing) 
... fill in a 
dim b = a.ToList() 
b.reverse() 

的優點則是一個類型可以是IEnumerable的(的T),它仍然能工作。

我自己測試過這一點,它一直是真實的,b是一個新的對象。問題是這樣的:

是否保證未來的實現會表現相同或者這種行爲是否是實現中的事故?

一個明顯的'優化'將返回對原始對象的引用,如果它已經是一個列表,這當然意味着第二個版本會顛倒原始列表。

+0

相關:[?ToList() - 它創建一個新的列表]( http://stackoverflow.com/q/2774099/1149773) – Douglas

回答

1

基於此source,我會假設它確實如此,但如果msdn文章中提到的查詢是空的,那麼它只會返回一個空列表。

鑑於您沒有設法反駁這一點,您可能需要對此進行進一步的研究才能找到真正的答案。

1

我不明白這只是一個實現細節。

IEnumerable<T>並不一定是一個列表。只是可以枚舉的東西。所以ToList()沒有別的選擇,只能遍歷整個枚舉並創建一個包含所有結果的新列表。

我能想到的唯一警告是如果他們在ToList裏面專門檢查輸入的類型是List<T>並且只是返回一個對它的引用。

但是,這將破壞現有的代碼,它永遠不會發生。

+0

一些IEnumerable方法肯定是類型檢查。 – argaz

+0

@argaz - 的確如同「Count()」一樣。但是這樣做會檢查'ToList()',以便在某些情況下它會創建一個副本,而在其他情況下,參考不會發生。只要他們不能爲所有枚舉類型創建一個引用(他們不能),他們就無法爲其中的任何枚舉創建引用。 –

+0

通常情況下,ToX()會創建一個新的引用,而AsX()會返回一個現有的引用(如果存在的話),並創建一個新引用,如果不存在引用。 (https://jira.codehaus.org/browse/GROOVY-1133) – nicodemus13

1

從它的documentation

從IEnumerable

這意味着一個新的實例創建一個列表。

您可一定要創建一個使用一個新的列表:

dim b =New List(Of T)(input) 其中input是一個IEnumerable(Of T)已

+0

感謝提醒我可以明確地調用構造函數。這確實會保證一個新的例子。 –