2011-05-25 41 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