C# 元组与列表的考虑因素

7

元组和列表的不同属性通常决定了我们在使用时应该选择哪一种。其中,元组是异构的(heterogeneous),而列表是同构的(homogeneous);元组是不可变的(immutable),而列表是可变的(mutable)。

然而,在其他场景下,这两种数据类型都可以同样适用。因此,元组和列表在内存和/或性能方面有何影响,这也将指导我们做出合适的选择。

谢谢!


1
我不认为这是一个适合在SO上讨论的话题,因为它们的意图有所不同,所以通常并没有在它们之间做出选择。 当你需要使用元组时,尝试使用列表是完全不自然的。决策应该在了解内容(即领域)的基础上进行,而不能事先确定。此外,您还应考虑集合的大小(以及是否可以动态增长)。 - Adriano Repetti
通常我们使用元组来存储集合的复合键。最近在QA过程中,我们有一个需求变更,并确定最少侵入性的代码更改是从方法返回两个值(int)。我们使用了Tuple<int, int>,但也可以使用List<int>。 - Seymour
1个回答

14

除了您提到的内容之外,还有一个非常重要的区别是元组最多只能包含八个项目。(好吧,您可以使用另一个元组作为最后一个元组参数类型来技术性地创建任意大的元组,但我认为您必须稍微疯狂才能真正这样做。)

与 Python 等语言中的元组不同,C# 中的元组不能真正用作通用数据结构。在 C# 中,元组的最常见用例之一是从函数返回多个值,或将多个值传递给某些原因只能接受一个值的函数(例如,将e.Argument传递给BackgroundWorker),或者在您无法费心制作自定义类且无法使用匿名类型的任何其他情况下。

由于您需要在编译时准确知道它们将包含多少项(以及哪些类型的项),因此元组的实际用途非常有限。另一方面,列表用于存储同类数据,您可能不知道将有多少项。我很想看看一段代码的示例,在您的话中,"任何一种数据类型都可能同样适用"。

此外,由于元组和列表解决完全不同的问题,因此比较其内存/性能影响可能相当有限。但是就其价值而言,元组被实现为类,而不是结构体,因此它们与列表一样存储在堆上,并且在函数之间传递时不会被复制,不像值类型。但是,它们确实实现了IStructuralEquatableIStructuralComparable接口,其Equals方法被实现为这将返回 true:new Tuple<int>(1).Equals(new Tuple<int>(1))(同时,new List<int>() { 1 }.Equals(new List<int>() { 1 })是 false)。


4
+1,但需要添加一条注释,即元组不可枚举 :-) 并且您无法在其上使用LINQ :-) :-) - xanatos
+1 @adkSerenity 但我认为元组并不是一个很好的通用解决方案(在我看来只适用于LINQ中间值),因为你会失去名称。如果你有两个整数,你总是要依靠文档来知道哪个是哪个,一个带有适当名称的自定义结构/类更清晰、更少出错,并且签名不会因为添加另一个元素而改变(这对于元组来说并不成立)。 - Adriano Repetti
@xanatos:你非常错了。看这个例子:http://www.dotnetperls.com/orderbydescending - boctulus
1
@Boctulus 那个例子是对一个元组数组进行排序,而不是对单个元组的元素进行排序。Tuple<int, int>[] tuples = ... tuples.OrderByDescending(...) - xanatos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接