Microsoft收集指南:对几个部分感到困惑

时间:2017-05-10 01:11:35

标签: c# .net collections ienumerable icollection

我正在关注微软的Guidelines for Collections,我发现有几个部分难以理解:

X不要在公共API中使用ArrayListList<T> 。这是否意味着我应该完全避免返回List<T>,或者我可以将其作为IEnumerable / IList返回,但不能明确地返回List<T>

✓请尽可能使用最不专业的类型作为参数类型。将集合作为参数的大多数成员使用IEnumerable<T>接口。在看到ReSharper抱怨“可能多次枚举IEnumerable”之后,我认为当我期待预先计算的有限的对象集合(即不是惰性流)时,采用(并返回)ICollection<T>是一个更好的主意。 )。不是这样的吗?

✓使用Collection<T>Collection<T>的子类来表示属性或返回表示读/写集合的值。为什么不使用ICollection<T>?我认为接口比具体类更可取。

1 个答案:

答案 0 :(得分:8)

这些guidleines的存在是为了促进设计方法的灵活性,它们接受的参数以及它们作为返回类型返回的内容。

如果从方法返回List<T>,该方法永远不会返回 List<T>的任何内容。在某些情况下这可能没什么问题,但在其他情况下则不然。例如,考虑一种方法,该方法返回在特定时间段内登录的用户集合。如果此方法仅返回List<T>,则必须在一次传递中获取并返回所有用户,因为这些是List的语义:一旦方法返回,您将获得具有总计数的所有项目。这可能是一个问题,如果用户数量是几万 - 可能需要很长时间才能获得所有记录,并且它们可能占用大量内存。

如果此方法返回IEnumerable<T>,则无法计算或立即获取所有项目 - 调用者可以遍历项目集合但不能一次性获取所有项目。这允许被调用的方法返回一个对象(实现IEnumerable<T>),该对象收集sevaral小批量中的数据并按要求逐个返回。

此外,许多不同的集合类型实现IEnumerable<T>,因此此方法的另一个实现可能实际上决定返回列表实例,强制转换为IEnumerable<T>。调用方法不会知道或关心,因为它期望的是IEnumerable<T>。硬编码列表类型不是这种情况 - 它不能与其他任何东西交换,因为它已经尽可能具体。

通常,泛型集合接口将是任何方法最灵活的输入参数/返回类型 - 一个接口将允许您以多种方式实现它,模拟它等等所以你有很多灵活控制传递或返回的内容。接口也不一定(必然)具有语义限制,随着产品的发展可能会变得不方便。

至于第一个建议,ArrayList是一个非常糟糕的类型,在.NET 2.0之后不应该使用,因为泛型类型在各方面都要好得多。