2011-05-25 38 views
1

我有一個代碼塊:提供類型兼容性和LINQ神祕

List<OneFeat> Feats; 
... 
List<OneFeat> Results = new List<OneFeat>(0); 
foreach (OneFeat Test in Feats) 
    if (String.Compare(Test.Name, Target, true) == 0) 
     Results.Add(Test); 
return Results; 

ReSharper的:

List<OneFeat> Results = new List<OneFeat>(0); 
Results.AddRange(Feats.Where(Feat => String.Compare(Feat.Name, Target, true) == 0)); 
return Results; 

這當然工作。然而,它創建一個列表,並將其添加到一個空列表,所以我試圖把它簡化爲:

return Feats.Where(Feat => String.Compare(Feat.Name, Target, true) == 0)); 

這將無法編譯,因爲它要鑄造。如果我添加轉換,它會在運行時失敗。

有什麼辦法可以在不復制結果列表的情況下對其進行編碼嗎?

回答

1

或者你可以在聲明的末尾添加.ToList()如下:

return Feats.Where(Feat => String.Compare(Feat.Name, Target, true) == 0)).ToList(); 
+0

這仍然創建一個副本,它只是將複製操作移動到.NET運行時庫中。 – 2011-05-25 03:28:19

+0

我沒有得到的是爲什麼投下一個被接受的答案? – Dimitri 2011-05-25 12:22:58

1

如果您只想列舉匹配的專業列表,然後將返回類型更改爲IEnumerable<OneFeat>。如果您必須返回實際列表,則必須複製該列表,因爲原始專長對象不代表匹配Test.Name的專長的子集。

3

啊哈,列出VS枚舉!

然而,它的創建列表和 它添加到一個空列表

不,它不是創建一個列表 - 否則你的最後一行是可行的。它將一個IEnumerable添加到列表中。

A Where運算符返回IEnumerable,它不是'列表' - 它更像是一個鬆散的,可迭代的和非具體的集合。

當您撥打AddRange時,此集合被迭代並添加到空列表中。我期望這與簡單地在結果上調用ToList非常相似。

這個概念起初有點難以理解,但想起IEnumerable作爲返回數據而不是數據集合的函數。如果您創建了由where子句過濾的項目列表,然後更改這些項目的值,則列表不會更改 - 它已經創建,並且項目不會根據這些值進行刪除或添加(除非您明確這樣做)。

但是,通過枚舉,只有在需要時纔會從基礎集合中緩慢地檢索項目。所以你可以通過一個集合中的where子句過濾枚舉項目,然後更改所有的值,以便沒有匹配過濾器,並且當從枚舉中檢索時它將是空的。

+0

現在我看到 - AddRange調用可以接受枚舉以及列表。 – 2011-05-25 01:39:41

+0

@Loren - 是的,在你的代碼中你添加一個枚舉,而不是一個列表。 – 2011-05-25 01:47:57