我有一段代码:
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));
哪个不会编译,因为它想要一个演员。如果我添加了强制转换,它会在运行时失败。
有没有办法在不复制结果列表的情况下对此进行编码?
答案 0 :(得分:3)
Aha,Lists vs Enumerations!
然而,它正在创建一个列表和 将其添加到空列表
不,它没有创建列表 - 否则你的最后一行会起作用。它正在为列表添加IEnumerable
。
Where
运算符返回IEnumerable
,它不是“列表” - 它更像是一个松散,可迭代和非具体的集合。
当您调用AddRange
时,将迭代此集合并将其添加到空列表中。我希望这与简单地在结果上调用ToList
非常相似。
这个概念起初有点难以理解,但将IEnumerable
视为返回数据而不是数据集合的函数。如果您创建了由where子句筛选的项目列表,然后更改这些项目的值,则列表不会更改 - 它已经创建,并且不会根据这些值删除或添加项目(除非您明确地这样做)。
但是,使用枚举,只有在需要时才会懒惰地从基础集合中检索项目。因此,您可以对集合中的where子句进行过滤的项进行枚举,然后更改所有值,使其不与过滤器匹配,并且从枚举中检索时它将为空。
答案 1 :(得分:1)
如果您只想枚举匹配的Feats列表,请将返回类型更改为IEnumerable<OneFeat>
。如果必须返回实际列表,则必须复制它,因为原始Feats对象不代表与Test.Name匹配的专长子集。
答案 2 :(得分:1)
或者您可以在Where语句的末尾添加.ToList(),如下所示:
return Feats.Where(Feat => String.Compare(Feat.Name, Target, true) == 0)).ToList();