在编写接受可枚举类型的函数时,很多时候我会遇到这种混乱。从以下选项中可以看出哪种api更好:
public void Resolve(Func<bool>[] howtos)
public void Resolve(IEnumerable<Func<bool>> howtos)
public void Resolve(List<Func<bool>> howtos)
我通常根据以下内容做出决定: 如果需要通过添加或删除项来修改输入,则使用List,否则使用IEnumerable。不确定数组选项。
在决定暴露api时是否还需要考虑其他问题?是否有任何经验法则可以清楚地确定哪种情况应优先于另一种?
由于
答案 0 :(得分:4)
您应始终接受限制性最小的参数类型。
这意味着IEnumerable<T>
,ICollection<T>
或IList<T>
这样,客户端可以自由地传递任何类型的实现,例如数组HashSet<T>
或ReadOnlyCollection<T>
。
具体来说,如果您只需要迭代数据,则需要IEnumerable<T>
;如果您还想添加或删除项目,或者如果您需要知道大小,则应ICollection<T>
IList<T>
{{1}} 1}}如果你需要随机访问(索引器)。
答案 1 :(得分:2)
我做出这个决定的主要因素是
Resolve实际上对该系列做了什么?
如果Resolve没有以任何方式改变集合,那么我绝对更喜欢IEnumerable<Func<bool>>
签名。它允许最大数量的用例,并且最准确地表达API的意图。我会假设任何采用更具体类型的内容(如List<T>
)都打算修改传入的集合。看到IEnumerable<T>
给了我一些保证,只是简单地枚举了这个集合。
如果Resolve正在改变集合,那么我希望List<T>
签名表明突变确实是可能的。我们可能会通过获取并返回IEnumerable<T>
来创建一个流畅的界面。这在很大程度上取决于Resolve的方法类型。当我选择一个而不是另一个时,很难概括。
答案 2 :(得分:1)
你的方式听起来不错。我唯一要改变的是IList<T>
而不是List<T>
。允许用户例如验证您要添加到列表中的任何内容。