列表和序列之间的区别

时间:2010-04-13 05:27:42

标签: c# f# list sequences

我正在尝试理解序列和列表之间的区别。

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

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

3 个答案:

答案 0 :(得分:7)

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

序列(由IList<T>表示)是只读的,仅向前的,一次一个项目,并且可能是无限的。当然,序列的任何一个实现也可以是一个列表(例如IEnumerable<T>)但是当你将它作为一个序列处理时,你基本上可以迭代它(重复),那就是它

答案 1 :(得分:4)

我认为混淆可能源于像List<T>这样的集合实现接口IEnumerable<T>这一事实。如果您通常具有子类型关系(例如,具有两个子类型ShapeRectangle的超类型Circle),则可以将该关系解释为“is-a”层次结构。

这意味着可以说“Circle Shape”,同样,人们会说“List<T> IEnumerable<T>“,即”list 序列“。这是有道理的,因为列表是序列的特殊类型。通常,序列也可以懒惰地生成并且是无限的(并且这些类型也不能是列表)。列表无法生成的(完全有效)序列的示例如下所示:

// 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#中使用频率较低。)

答案 2 :(得分:2)

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

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

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

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

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