如何决定api签名

时间:2011-03-02 18:01:58

标签: c# .net api class-design

在编写接受可枚举类型的函数时,很多时候我会遇到这种混乱。从以下选项中可以看出哪种api更好:

public void Resolve(Func<bool>[] howtos)

public void Resolve(IEnumerable<Func<bool>> howtos)

public void Resolve(List<Func<bool>> howtos)

我通常根据以下内容做出决定: 如果需要通过添加或删除项来修改输入,则使用List,否则使用IEnumerable。不确定数组选项。

在决定暴露api时是否还需要考虑其他问题?是否有任何经验法则可以清楚地确定哪种情况应优先于另一种?

由于

3 个答案:

答案 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>。允许用户例如验证您要添加到列表中的任何内容。