从函数返回多个相同类型的对象时,首选的容器类型是什么?
返回一个简单的数组(比如MyType [])是不是很好,或者你应该将它包装在一些通用容器中(比如ICollection
谢谢!
Eric Lippert有一篇很好的文章.如果您无法阅读整篇文章,答案是:返回界面.
IEnumerable
使用a 返回yield return
.
我会返回一个,IList
因为它为您的功能的消费者提供了最大的灵活性.这样,如果你的函数的使用者只需要枚举他们可以这样做的序列,但是如果他们想要将序列用作列表,他们也可以这样做.
我的一般经验法则是接受限制性最小的类型作为参数,并返回最丰富的类型.当然,这是一种平衡行为,因为您不想将自己锁定到任何特定的接口或实现中(但总是尝试使用接口).
这是API开发人员可以采取的最不自负的方法.决定你的函数的消费者将如何使用他们发送给你的东西并不取决于你 - 这就是为什么你会IList
在这种情况下返回给他们最大的灵活性.同样出于同样的原因,您永远不会想知道消费者会向您发送什么类型的参数.如果您只需要迭代作为参数发送给您的序列,则将参数设为IEnumerable
而不是a List
.
编辑(一氧化碳):由于看起来问题不会被关闭,我只想添加一个关于此问题的链接:为什么数组是有害的
为什么不List
呢?
从其他人提到的Eric Lippert帖子中,我想我会强调这一点:
如果我需要一个我将使用的序列
IEnumerable
,如果我需要从连续数字到数据的映射我将使用aList
,如果我需要跨越任意数据的映射我将使用aDictionary
,如果我需要一个集合我将使用HashSet
.我根本不需要任何数组,所以我几乎从不使用它们.他们没有解决我比其他工具更好的问题.
如果要返回的集合是只读的,这意味着您永远不希望更改集合中的元素,那么请使用IEnumerable
.这是不可变的只读序列(至少从枚举本身的角度来看)元素的最基本表示.
如果您希望它是可以更改的自包含集合,请使用ICollection
或IList
.
例如,如果要返回搜索特定文件集的结果,请返回IEnumerable
.
但是,如果要在目录中公开文件,则会显示IList/ICollection
,因为您可能希望可能更改集合的内容.
我听过的一条很好的建议是:
在你接受的内容中要自由,在你所提供的内容中要准确.
在设计API方面,我建议你应该返回一个接口,而不是一个具体的类型.
以您的示例方法为例,我将其重写如下:
public IList
关键是您的内部实现选择 - 使用List - 不会向调用者显示,但您将返回适当的接口.
Microsoft自己的框架开发指南建议不要返回特定类型,有利于接口.(对不起,我找不到这个链接)
同样,您的参数应该尽可能通用 - 而不是接受数组,接受适当类型的IEnumerable.这与数组以及列表和其他有用类型兼容.
再次采用您的示例方法:
public IListFoo(IEnumerable bar) { List retList = new List (); // Blah, blah, [snip] return retList; }