代码之家  ›  专栏  ›  技术社区  ›  csharptest.net

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

  •  11
  • csharptest.net  · 技术社区  · 15 年前

    public interface Foo
    {
        Bar[] Bars { get; }
        IEnumerable<Bar> Bars { get; }
        ICollection<Bar> Bars { get; }
        IList<Bar> Bars { get; }
    }
    

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

    public interface Foo
    {
        void Do(IEnumerable<Bar> bars);
        Bar[] Bars { get; }
    }
    

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

    8 回复  |  直到 15 年前
        1
  •  18
  •   JaredPar    15 年前

    我的偏好是 IEnumerable<T>

    另一个很好的例子是 ReadOnlyCollection<T> . 它允许所有有趣的.Count和Indexer属性,并明确地告诉消费者“你不能修改我的数据”。

        2
  •  15
  •   Andrew Hare    15 年前

    我不返回数组——在创建API时,它们确实是一种糟糕的返回类型——如果您确实需要可变序列,请使用 IList<T> ICollection<T> 接口或返回混凝土 Collection<T> 相反

    Arrays considered somewhat harmful 埃里克·利珀特:

    程序设计语言教材 前几天征求我对这件事的意见 是否是初学者程序员

    而不是回答这个问题 关于数组的意见,我如何使用 数组,我们期望数组是什么样子的 没有时间把它缩短。

    让我先说,当你 阵列在未来世界中的角色。

        3
  •  8
  •   Sam Harwell    15 年前

    ReadOnlyCollection<T> (只读)或 IList<T> (读/写)。这是最灵活和最有表现力的。对于非索引集合,请使用 IEnumerable<T> (只读)或 ICollection<T> (读/写)。

    方法参数应使用 IEnumerable<T> 除非他们1)需要向集合添加/删除项目( i收集<T> IList<T> as IList<T> .ToList() 当这在实现中失败时。

        4
  •  1
  •   Robban    15 年前

    我更喜欢IEnumerable,因为它是最高级的界面,让最终用户有机会按照自己的意愿进行重播。即使这可以为用户提供最基本的功能(基本上只是枚举),但它仍然足以满足几乎任何需要,特别是扩展方法ToArray()、ToList()等。

        5
  •  1
  •   Joel Coehoorn    15 年前

    我从编写最有用的代码的角度考虑这一点:可以做更多事情的代码。

    换句话说,这意味着我愿意接受 最弱的 接口可以作为方法参数,因为这使我的代码在更多地方都很有用。在这种情况下,这是一个 IEnumerable<T>

    这也意味着我喜欢返回 接口,以便依赖于该方法的代码可以轻松地执行更多操作。在这种情况下,这将是 IList<T> . 请注意,这并不意味着我将构造一个列表以便返回它。这只是意味着如果我 已有 有一些实现了 IList<T>

    请注意,对于返回类型,我有点不传统。一种更典型的方法是还从方法返回较弱的类型,以避免将自己锁定在特定的实现中。

        6
  •  0
  •   to StackOverflow    15 年前

    IEnumerable<T>对于延迟评估迭代非常有用,特别是在使用方法链接的场景中。

    这也是对调用方的一个指示,表明集合实际上已经具体化。因此,调用方可以迭代返回的集合,而不会从数据访问层获得异常。这可能很重要。例如,服务可以从返回的集合生成流(例如SOAP)。如果在生成流时由于延迟的计算迭代而从数据访问层抛出异常,这可能会很尴尬,因为抛出异常时输出流已经部分写入。

        7
  •  0
  •   Travis Heseman    15 年前

    由于将Linq扩展方法添加到IEnumerable<T>,我发现我对其他接口的使用已经大大减少了;大概80%左右。我曾经使用列表<T>因为它有接受委托进行懒惰评估的方法,比如Find、FindAll、ForEach等等。由于这可以通过System.Linq的扩展获得,因此我将所有这些引用替换为IEnumerable<T>参考资料。

        8
  •  0
  •   eglasius    15 年前

    我不会使用数组,它是一种允许修改的类型,但没有添加/删除。。。有点像这群人中最坏的。如果我想允许修改,那么我将使用支持添加/删除的类型。

    当您想要阻止修改时,您已经在包装/复制它,所以我看不出IEnumerable或ReadOnlyCollection有什么问题。我以后会和你一起去。。。我不喜欢IEnumerable的一点是,它本质上是懒惰的,但是当您仅使用预加载的数据来包装它时,调用与它一起工作的代码往往会假定预加载的数据或有额外的“不必要的”行:(…在更改期间可能会得到不好的结果。