我有一个代码块:
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));
它不会编译,因为它需要强制转换。如果我添加强制转换,它将在运行时失败。
有没有任何方法可以在不复制结果列表的情况下对此进行编码?
Aha,列表与枚举!
然而,它正在创建一个列表将其添加到空列表
不,这不是在创建一个列表——否则你的最后一行就行了。它正在向列表中添加一个IEnumerable
。
Where
运算符返回一个IEnumerable
,它不是"list",它更像是一个松散的、可迭代的、非具体的集合。
当您调用AddRange
时,该集合将被迭代并添加到空列表中。我认为这与简单地对结果调用ToList
非常相似。
这个概念一开始有点难以理解,但可以将IEnumerable
看作是返回数据的函数,而不是数据的集合。如果您制作了一个由where子句筛选的项目列表,然后更改这些项目的值,则该列表不会更改——它已经创建,并且不会根据这些值删除或添加项目(除非您明确这样做)。
但是,使用枚举时,仅在需要时才从基础集合中延迟检索项。因此,您可以对集合中由where子句筛选的项进行枚举,然后更改所有值,使其与筛选器不匹配,当您从枚举中检索时,它将为空。
或者您可以添加。ToList()在Where语句末尾,如下所示:
return Feats.Where(Feat => String.Compare(Feat.Name, Target, true) == 0)).ToList();
如果您只想枚举匹配的特征列表,那么将返回类型更改为IEnumerable<OneFeat>
。如果必须返回一个实际列表,则必须复制该列表,因为原始的Feats对象并不代表与测试匹配的专长子集。名称