我在 WebApi 中应该使用 IEnumerable 还是 List 作为参数?

27 浏览
0 Comments

我在 WebApi 中应该使用 IEnumerable 还是 List 作为参数?

我对枚举器和LINQ的工作方式有一些疑问。考虑这两个简单的选择:

List sel = (from animal in Animals 
                    join race in Species
                    on animal.SpeciesKey equals race.SpeciesKey
                    select animal).Distinct().ToList();

或者

IEnumerable sel = (from animal in Animals 
                           join race in Species
                           on animal.SpeciesKey equals race.SpeciesKey
                           select animal).Distinct();

我改变了原始对象的名称,以便这看起来像一个更通用的示例。查询本身并不那么重要。我想要问的是:

foreach (Animal animal in sel) { /*do stuff*/ }

  1. 我注意到如果我使用IEnumerable,当我调试并检查“sel”时,在那种情况下“sel”是IEnumerable,它有一些有趣的成员:“内部”,“外部”,“innerKeySelector”和“outerKeySelector”,这最后2个看起来是委托。 “内部”成员不包含“Animal”实例,而是包含“Species”实例,这对我来说非常奇怪。 “外部”成员包含“Animal”实例。我假设两个委托决定了哪个进入它以及什么离开它?
  2. 我注意到如果我使用“Distinct”,“inner”包含6个项(这是不正确的,因为只有2个是不同的),但“outer”确实包含正确的值。再次,可能委托方法决定了这一点,但这比我对IEnumerable所知道的更多一些。
  3. 最重要的是,哪一个选项在性能上最好?

邪恶的通过.ToList()进行的List转换?

还是直接使用枚举器?

如果可以的话,请也解释一下IEnumerable的使用,或提供一些解释这种使用的链接。

admin 更改状态以发布 2023年5月23日
0
0 Comments

这里有一篇非常好的文章,由Claudio Bernasconi的TechBlog撰写,链接如下:何时使用IEnumerable、ICollection、IList和List

以下是关于场景和功能的基本要点:

enter image description here
enter image description here

0
0 Comments

IEnumerable 描述了行为,而List是该行为的实现。当您使用 IEnumerable 时,您给编译器一个机会,推迟工作直到以后,可能会在过程中进行优化。如果您使用 ToList(),则会立即强制编译器实例化结果。

每当我“叠加”LINQ表达式时,我使用 IEnumerable,因为仅指定 behavior,我给LINQ一个机会推迟评估并可能优化程序。记住,LINQ在枚举之前不生成查询数据库的SQL语句。考虑一下:

public IEnumerable AllSpotted()
{
    return from a in Zoo.Animals
           where a.coat.HasSpots == true
           select a;
}
public IEnumerable Feline(IEnumerable sample)
{
    return from a in sample
           where a.race.Family == "Felidae"
           select a;
}
public IEnumerable Canine(IEnumerable sample)
{
    return from a in sample
           where a.race.Family == "Canidae"
           select a;
}

现在你有一个选择初始样本(“AllSpotted”)的方法,以及一些过滤器。那么现在你可以这样做:

var Leopards = Feline(AllSpotted());
var Hyenas = Canine(AllSpotted());

那么使用 List 是否比 IEnumerable 更快?只有在您想要防止多次执行查询时才是。但总体而言更好吗?好吧,在上述示例中,Leopards和Hyenas都被转换为单个SQL查询,并且数据库仅返回相关行。但是,如果我们从 AllSpotted() 返回了一个List,则可能运行得更慢,因为数据库可能会返回比实际需要的数据量更大,我们浪费时间在客户端过滤。

在程序中,将查询转换为列表推迟到最后可能更好,因此,如果我要枚举Leopards和Hyenas超过一次,我会这样做:

List Leopards = Feline(AllSpotted()).ToList();
List Hyenas = Canine(AllSpotted()).ToList();

0