在编写接受可枚举类型的函数时,我多次面临这种困惑。从以下选项中公开哪个 API 会更好:
public void Resolve(Func<bool>[] howtos)
public void Resolve(IEnumerable<Func<bool>> howtos)
public void Resolve(List<Func<bool>> howtos)
我通常根据以下因素做出决定: 如果需要通过添加或删除项目来修改输入,则使用
List<T>
,否则使用 IEnumerable<T>
。不确定 Array
选项。
在决定公开的API时是否还需要考虑其他点?是否有任何经验法则可以清楚地确定在哪些情况下应该优先选择其中一个?
您应该始终接受限制最少的参数类型。
这意味着
IEnumerable<T>
、ICollection<T>
或 IList<T>
。HashSet<T>
或ReadOnlyCollection<T>
。
具体来说,如果您只需要迭代数据,则应选择
IEnumerable<T>
;如果还想添加或删除项目,或者需要知道大小,则应选择 ICollection<T>
;如果需要随机访问,则应选择 IList<T>
(索引器)。
我做出这个决定的首要因素是
Resolve 实际上对集合做了什么?
如果 Resolve 不会以任何方式改变集合,那么我绝对更喜欢
IEnumerable<Func<bool>>
签名。 它允许最大数量的用例并最准确地表达 API 的意图。 我会假设任何采用像 List<T>
这样更具体的类型的东西都打算修改传入的集合。 看到 IEnumerable<T>
让我确信该集合只是被枚举出来。
如果 Resolve 正在改变集合,那么我更喜欢
List<T>
签名来表明突变确实是可能的。 我们可能会通过获取并返回IEnumerable<T>
来创建一个流畅的界面。 这在很大程度上取决于 Resolve 方法的类型。 很难概括我何时会选择其中之一而不是另一个。
你的方法听起来不错。我唯一要改变的是让它变成
IList<T>
而不是 List<T>
。例如,允许用户验证您添加到列表中的任何内容。