Why return a collection interface rather than a concrete type?
我在其他人的代码中注意到,返回泛型集合的方法几乎总是返回一个接口(例如IEnumerable或IList,而不是具体的实现。
我有两个相关的问题。首先,为什么(如果有的话)认为返回接口更好?其次,是否有包含排序方法的集合接口(如List)?
对于第一个问题:如果您返回一个接口,您将保留更多的灵活性。稍后可以更改实现以返回不同的具体类型。另一方面,它显然给了调用者较少的信息,因此他们可能无法执行某些操作。(例如,如果您返回List,调用方可以使用convertall等…如果您只声明返回IList,它们就不能这样做。在某些情况下,指定具体的类型是值得的;我通常喜欢至少从接口开始,如果我发现我经常想使用可用的额外方法,我只会移动到将具体的类型作为返回类型。
其次,没有标准的收集接口具有Sort方法。另一方面,您可以编写一个扩展方法来对任何IList进行排序。就我个人而言,我通常更喜欢Linq OrderBy、OrderByDescending、ThenBy和ThenByDescending方法……尽管它们返回一个新的序列,而不是在适当的位置进行排序。
来自C-列表或IList
If you are exposing your class through
a library that others will use, you
generally want to expose it via
interfaces rather than concrete
implementations. This will help if you
decide to change the implementation of
your class later to use a different
concrete class. In that case the
user's of your library won't need to
update their code since the interface
doesn't change.
If you are just using it internally,
you may not care so much, and using
List may be ok.
- 谢谢你-非常有帮助。这就是问题所在——我不是为了外部使用而写图书馆。我正在为一家我是唯一开发者的公司写一个内部网。这会使我更难从这些事情中看到目的。
- 是的,如果它是纯内部的,并且您确定它不会暴露在公共或软件的多个部分中,那么返回一个list对象应该是可以的。但是,例如,如果它是一个类库,虽然它现在仅在您的应用程序中使用,但您可能希望扩展应用程序并再次使用该库,因此,您将被约束为列出而不是自己的内建。
我们使用接口在实现中给予我们更多的灵活性。因此,如果方法的返回类型为IEnumerable,则可以将它从列表返回的对象更改为数组,而不更改依赖于该方法的对象。
它也很有表现力:如果您返回一个IEnumerable,当对象被使用时,编码人员很清楚我们只关心它是某种集合,而不是特定的类型。
我不能代表每个人说话,但一般来说,我这样做只是因为我只想返回我需要的东西。当你只需要一个可重复的可枚举集合时,为什么还要返回一个完整的集合呢?
对于问题的另一部分,您可以始终使用ilist,然后使用linq进行排序:
- @投反对票的人愿意发表评论吗??
- 谢谢,我现在明白了。我不知道我有可用的orderby,因为它是一个扩展方法,我没有使用名称空间。
- 伟大的。是的,LINQ的扩展方法很好。
- @斯宾农:当然,我会对我的投票结果发表评论:我同样可以说,作为一个调用者,我更愿意将最具体的集合类型返回给我。如果代码返回一个List,那么我可以按原样使用它,或者将它用作IList或IEnumerable等,它会给调用者更多的选择。但这不是真正的问题。它防止在方法的实现发生更改时破坏调用代码。如果方法返回一个IEnumerable,那么我可以将实现更改为使用支持该接口的任何容器,而不需要修改调用代码。
- @沙德罗普,我不明白。集合是特定的,基于集合中的类型,而不是包含项的类型。包含项只决定您可以使用哪些功能。但是,如果您需要更多的功能,您总是可以基于ilist创建一个新的列表。我不认为我理解你的论点,因为我不知道你说的是好是坏。不过,谢谢你的评论。对自己的想法很感兴趣。
- @斯宾农:我认为你提出的理由是错误的。这并不是真正的让调用代码访问它所需要的东西,因为——正如我所说的——给调用代码更多的选择并让它自己选择同样有意义。如前所述,选择返回IEnumerable而不是具体的List的真正原因是保护调用代码不受实现更改的影响。对不起,但我认为区别非常重要。
- @沙德罗普不需要为投票否决道歉。如果这就是你的感受,那就是你的感受。我只是好奇为什么投反对票,因为我的回答似乎和其他人说的一致。注意所选答案第一段的最后一句话。那个用户提到了类似的想法。只返回实际需要的最小值。如果你发现你需要更多的选择,那么你可以返回更多。但无论如何,谢谢你的原因。