类型兼容性和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));

它不会编译,因为它需要强制转换。如果我添加强制转换,它将在运行时失败。

有没有任何方法可以在不复制结果列表的情况下对此进行编码?

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对象并不代表与测试匹配的专长子集。名称

相关内容

  • 没有找到相关文章

最新更新