数据对象属性的最佳实践:IEnumerable与Array

时间:2015-04-09 10:08:12

标签: c# ienumerable

简短问题:将数据对象属性声明为IEnumerable是否可以,或者它应该是Array

背景

我刚刚在项目中发现了一个导致性能问题的错误。原因是IEnumerable已被多次迭代。但这只是初看起来很简单。我认为那里存在一个设计缺陷,允许这种情况发生。

更深入的调查显示,一个方法GetAllUsers返回了一个UsersResponse对象,其中一个属性为IEnumerable<T> UsersList。实现缓存时,显然整个UsersResponse对象都被缓存,并且当时工作正常,因为GetAllUsers已将数组分配给IEnumerable<T> UsersList。后来GetAllUsers的实施发生了变化,由于某些原因,开发人员认为ToArray()调用是多余的。所以我认为问题在于UsersResponse对象没有经过精心设计,并且为它的工厂方法提供了太多的自由。另一方面,缓存包含IEnumerable属性的对象原则上也是无用的。

所以我们回到我的一般设计数据对象的问题:当你声明它时,不知道它将来会被缓存,或者除了当前的需要以外它将如何以其他方式使用,是吗?可以将其属性声明为IEnumerable,将谨慎使用的责任放在其他开发人员身上,或者从一开始就必须Array

我搜索过的内容:

我发现的唯一建议是Jon Wagner's blog post,他建议在建立后立即“密封”LINQ链。但这与构建IEnumerable相关,而不是将其存储在实体属性中。虽然结合原则尽可能返回特定类型,但它可能意味着将属性声明为Array

3 个答案:

答案 0 :(得分:1)

当我考虑API设计时,我总是试图对消费者“好”。这意味着尽可能多地接受参数(如果可能),并尽可能多地提供返回值。如果你也购买了它,这意味着你应该在提供IEnumerable(或类似的)返回值的同时争取Array个参数。结果是API消费者的最大价值(即使最终是你自己)。

答案 1 :(得分:0)

我通常赞成Array方法,除非它被强制进入集合。 特别是当有很多数值计算时。

优点:

  • 紧凑型存储。 (hacky技术的概率)
  • []访问者。 (不适用于C#)
  • 多维数组的可读代码

最后但并非最不重要的是,坚持一个,绝不使用两者。将一个集合从Array转换为Collection是很糟糕的,反之亦然,这也没有用。

答案 2 :(得分:0)

应该使用满足要求的最抽象类型。如果您需要在DTO中存储“打开”查询,则使用ICollection<T>或(如果您需要索引访问权限)IList<T>来获取该属性。

使用array将指导您进行具体实施。这可能不是问题,或者可能在以后的某个时候变成痛苦。后者排除了array恕我直言。

顺便说一句:调用者有责任只在IEnumerable<T>上进行一次迭代。