2

我试图了解序列和列表之间的区别。

在 F# 中,两者之间有明显的区别。但是在 C# 中,我看到程序员将 IEnumerable 集合称为序列。是什么让 IEnumerable 成为一个序列,它返回一个对象以遍历集合?

也许真正的区别纯粹是在函数式语言中发现的?

4

3 回答 3

7

不是真的 - 你倾向于随机访问一个列表,以及能够快速获得它的计数等。不可否认的链接列表没有随机访问性质......但是他们没有实现IList<T>. 特定平台提供的设施与一般概念之间存在灰色地带。

序列(由 表示IEnumerable<T>)是只读的、只进的、一次一个项目,并且可能是无限的。当然,序列的任何一种实现也可能是一个列表(例如List<T>),但是当您将其视为一个序列时,您基本上可以(重复地)对其进行迭代,仅此而已。

于 2010-04-13T05:31:14.073 回答
4

我认为这种混淆可能是由于集合之类List<T>的实现接口这一事实引起的IEnumerable<T>。如果您通常具有子类型关系(例如Shape,具有两个子类型Rectangle和的超类型Circle),您可以将关系解释为“is-a”层次结构。

这意味着说“Circle 是一个 Shape”是完全可以的,类似地,人们会说“List<T> 是一个 IEnumerable<T>”,即“列表是一个序列”。这是有道理的,因为列表是序列的一种特殊类型。一般来说,序列也可以是惰性生成和无限的(这些类型也不能是列表)。无法由列表生成的(完全有效的)序列示例如下所示:

// C# version                           // F# version
IEnumerable<int> Numbers() {            let rec loop n = seq {
  int i = 0;                               yield n
  while (true) yield return i++;           yield! loop(n + 1) }
}                                       let numbers = loop(0)

这对于 F# 也是如此,因为 F#list类型也实现IEnumerable<T>了 ,但函数式编程并没有那么强调面向对象的观点(并且在 F# 中不太频繁使用启用“is a”解释的隐式转换)。

于 2010-04-13T13:40:10.720 回答
2

序列内容是按需计算的,因此您可以在不影响记忆的情况下实现例如无限序列。所以在C#中你可以写一个序列,例如

IEnumerable<int> Null() {
  yield return 0;
}

它将返回无限的零序列。你可以写

int[] array = Null().Take(10).ToArray()

尽管序列是无限的,但它将占用 10*4 字节的内存。如您所见,C# 确实区分了序列和集合

于 2010-04-14T07:00:33.830 回答