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

lfk*_*lfk 10 .net c# collections ienumerable icollection

我正在看微软的收藏指南,我发现有几个部分难以理解:

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

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

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

xxb*_*bcc 8

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

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

如果这个方法会返回一个IEnumerable<T>,那么就不会有计数或一次获取所有项目的承诺 - 调用者可以遍历项目集合但不能一次性获取所有项目.这允许被调用的方法返回一个对象(实现IEnumerable<T>),该对象收集sevaral小批量中的数据并按要求逐个返回它们.

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

通常,通用集合接口将是任何方法最灵活的输入参数/返回类型 - 接口将允许您以多种方式实现它,模拟它等等,因此您在控制方面具有很大的灵活性什么被传递或返回.界面也不(必然)具有语义限制,随着产品的发展可能变得不方便.

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