为什么通用列表AddRange返回void而不是列表?

Jos*_*eld 10 c#

namespace System.Collections.Generic
  public List<T>    
    public void AddRange(IEnumerable<T> collection)
Run Code Online (Sandbox Code Playgroud)

看起来这可能是一个故意的设计决定,不返回某些东西.我对此感到厌烦,期待AddRange"流利".

我只是好奇是否有人知道设计动机,如果有的话,什么也不回报?

d--*_*--b 24

AddRange在LINQ出局之前,这个方法是在.NET 2.0中添加的,当"流畅性"真的没有流行时.当时,没有人希望AddRange返回任何东西.另外,在该版本的.NET中,没有List对象的初始化程序,因此您必须将一堆项添加到列表中.AddRange提供了一个不必循环遍历和逐个添加对象的快捷方式.

等效的LINQ方法是 IEnumerable<T>.Concat()

  • 很好的答案,但并不完全正确。请注意,AddRange 方法是在 .NET 2.0 中添加的,因为整个 *class* 是在 2.0 中添加的。通用的 `List&lt;T&gt;` 自从发布以来就有了一个带有 `IEnumerable&lt;T&gt;` 参数的构造函数(我想这就是你所说的“初始化器”的意思);`AddRange` 的价值在于它允许您随时添加项目序列,而不仅仅是在构造时添加。此外,还有一些甚至早于 .NET 2.0 的流畅 API 实例;Trisped 指出,我想到了“StringBuilder”。 (2认同)

pho*_*oog 4

其他答案(基本上)是正确的,但没有一个答案解决了为什么可能 AddRange返回某些内容的两种可能性。

这样做的原因之一是创建一个流畅的 API,如下所示:

list.Add(1).Add(2).Add(3);
list.AddRange(aGroupOfNumbers).AddRange(theNextGroupOfNumbers);
Run Code Online (Sandbox Code Playgroud)

为了实现这一点,列表只需在改变列表的方法末尾返回自身。正如 Trisped 所指出的,在引入StringBuilder仿制药之前就这样做了。List<T>

正如 Felix K. 暗示的那样,返回某些内容的另一个原因是类型是不可变的。如果列表是不可变的,则它不能在方法结束时返回自身,因为它不能改变自身;并且它不能再次返回 void,因为它不能改变自身。为了反映方法契约定义的更改,列表必须创建一个包含更改的新实例,然后,当然,它必须将该新实例返回给调用者。当谈到集合时,人们有时很难理解这一点,但有一种非常著名的类型具有这种行为方式:System.String。正如 db 所说,没有人期望列表返回任何内容,因为“经典”命令式编程风格在改变数据结构时使用 void 方法。

命名空间的设计者System.Collections.Generic可能没有想到为他们的类型提供流畅的 API,但如果他们这样做了,我可以看到他们可能会如何决定反对它。当然,StringBuilder 中的流畅 API 的情况比List<T>.