您更喜欢哪种接口:T [],IEnumerable <T>,IList <T>或其他?

csh*_*net 11 .net c# coding-style

好的,我希望整个社区能够帮助我们解决一段时间以来一直在进行的工作场所辩论.这与定义接受或返回某种类型列表的接口有关.有几种方法可以做到这一点:

public interface Foo
{
    Bar[] Bars { get; }
    IEnumerable<Bar> Bars { get; }
    ICollection<Bar> Bars { get; }
    IList<Bar> Bars { get; }
}
Run Code Online (Sandbox Code Playgroud)

我自己的偏好是使用IEnumerable作为返回值的参数和数组:

public interface Foo
{
    void Do(IEnumerable<Bar> bars);
    Bar[] Bars { get; }
}
Run Code Online (Sandbox Code Playgroud)

我对这种方法的论点是,实现类可以直接从IEnumerable创建一个List,并简单地使用List.ToArray()返回它.但是有些人认为应该返回IList而不是数组.我在这里遇到的问题是,现在你需要再次使用ReadOnlyCollection复制它,然后再返回.返回IEnumerable的选项对于客户端代码来说似乎很麻烦?

你喜欢/喜欢什么?(特别是关于将由组织外部的其他开发人员使用的库)

Jar*_*Par 18

我的偏好是IEnumerable<T>.任何其他建议的接口都给出了允许消费者修改底层集合的外观.这几乎肯定不是你想要做的,因为它允许消费者默默地修改内部集合.

另一个好的恕我直言,是ReadOnlyCollection<T>.它允许所有有趣的.Count和Indexer属性,并明确地向消费者说"你无法修改我的数据".

  • 在我工作过的任何应用程序中都是+1,至少,"IEnumerable"是你所需要的98%的时间. (3认同)
  • @Jared:你在合同类中放了一个`Contract.Ensures(Contract.Result <IList <T >>().IsReadOnly);) (2认同)

And*_*are 15

我没有返回数组 - 它们在创建API时确实是一种糟糕的返回类型 - 如果你真的需要一个可变序列使用IList<T>ICollection<T>接口或返回一个具体的Collection<T>.

另外我建议您阅读Eric Lippert 认为有些有害阵列:

前几天,我从编程语言教科书的作者那里得到了一个道德问题,要求我就初学者程序员是否应该学习如何使用数组提出意见.

我没有真正回答这个问题,而是给了他一长串我对阵列的看法,我如何使用数组,我们希望将来如何使用数组,等等.这有点长,但像Pascal一样,我没有时间缩短它.

让我首先说明,当你绝对不应该使用数组,然后对现代编程的未来以及数组在即将到来的世界中的作用进行更多的哲学思考.


Sam*_*ell 8

对于索引的属性集合(以及索引具有必要的语义含义),您应该使用ReadOnlyCollection<T>(只读)或IList<T>(读/写).这是最灵活和最富有表现力的.对于非索引集合,请使用IEnumerable<T>(只读)或ICollection<T>(读/写).

方法参数应该使用,IEnumerable<T>除非它们1)需要向集合添加/删除项目(ICollection<T>)或2)需要索引以用于必要的语义目的(IList<T>).如果该方法可以从索引可用性(例如排序例程)中受益,则它总是可以使用as IList<T>.ToList()在实现中失败时.