C#元组 - Tuple的实际用途是什么?

7

我在网上查看Tuple的示例,但我没有看到任何理想的使用方法。

也就是说,它似乎是存储变量的地方。

是否有任何实际用途的Tuple呢?我想做的是传入一个值到元组中,然后返回3个字符串值。


5
你的意思是,“将值传递给元组并让它返回三个值”是什么意思?元组除了存储数据外不会做任何其他事情。问一个元组有什么用就像问一个POCO有什么用一样。 - Kirk Woll
3
在提出这个问题之前,你是否研究过元组是什么?使用了哪些示例?也许考虑问一个更直接的问题,比如“这个<场景>是否适合使用元组?”等。我不会扣分,但在我看来,这真的不是一个非常好的问题。 - Nathan
8个回答

11

元组是列表的对应物。

虽然列表存储0-N个相同类型的项目,但元组存储1-M个(可能)不同类型的项目,其中N是无限的,而M是静态固定/定义的。

可以通过它们的名称(或“索引”)以强类型方式访问每个项目。

因此,它们类似于匿名类型(实际上,这更像是一个“记录”,而不是一个“元组”,因为名称可以任意选择):

new { _0 = value0, _1 = value1, /* etc, as needed */ }

但是元组类型是 名义上 类型化的(它们由一堆不同的类支持,就像 Action 或者 Func),因此一个具体的 元组类型可以被明确指定(例如在方法签名中),而匿名类型则无法使用。

虽然我会说 C# 中元组的实际用途受到了支持的缺乏的影响 (例如没有分解、没有应用等等),但在 Scala 等语言中它们被 经常地 使用。C# 的方式通常是“创建一个新的命名类型”,但也引入了 Tuple 类型作为另一种可用工具。

(元组非常有用的一个大的场景是中间计算-但是 C# 有匿名类型,就像 LINQ 中看到的那样,在大多数情况下执行在同一方法内完成的计算时会非常好用。)


7

微软.NET 4.0引入了一种称为Tuple的类型,它是一个异构数据的固定大小集合。与数组类似,元组具有不能更改的固定大小。但不同于数组的是,元组中的每个元素可以是不同的类型,并且元组能够为每个元素提供强类型保证。在某些情况下,使用自定义类型或结构体可能会很麻烦, 这时候元组非常方便。


与数组不同,元组(Tuple)中的项目是不可变的(在实例化后无法更改其值)。 - Salmonstrikes

4

Tuple是一个容器,您可以在其中存储任何内容。

对于3个项目,它被称为Triple。4个项目则为quadruple,依此类推。

基本上,您只需将项目放入其中即可。

这里有一个示例


1
这是不正确的,没有三元组或四元组。有3元组,4元组等。 - alex
1
你应该在维基百科上更改这个:http://en.wikipedia.org/wiki/Tuple - DarthVader
2
有关 Tuple 类的问题:http://msdn.microsoft.com/zh-cn/library/system.tuple.aspx - alex
一般来说,它应该是Triple、Quadruple,但在C#中并没有这样的东西。 - Chris Sinclair
1
是的,C# 是计算机科学的超集。 - DarthVader
@DarthVader 你的意思是“子集”。;) - Chris Sinclair

3

Tuple(元组)是一种有类型的、不可变的、通用的结构。它是一个有用的容器,可以存储概念上相关的数据。对于重要的事物来说,一个带注释成员和额外方法的简单类更加有用。但是Tuple可用于存储杂项但相关的信息。在信息隐藏方面,Tuple表现得不够好,但在作为有用的短期容器方面却表现出色。


2
一个实际应用场景:假设您想在软件的不同内部组件之间传递结构化数据列表。
  1. 您可以声明一个表示结构化数据的类。在这种情况下,此类理想情况下应该是无用的,它只包含一堆自动属性。您可能会将其声明为嵌入式类的接口(但然后必须使用接口名称作为前缀),或者在与接口相同的命名空间中声明。在某些情况下,这可能是定义唯一类以达到此目的的不必要的管道代码。
  2. 或者您可以使用元组。这样,您就不必为所有这些定义一个类,仍然可以保持类型安全。您可能会失去命名属性的优势,如果您有许多属性,甚至可能来自相同的类型,则可能会出现问题。
更具体的例子: 您想为第三方组件TreeListView设置列排序。您从控制器对象初始化排序,该对象调用视图上的正确函数(SortByColumns),该函数调用包装器类上的函数,该类围绕第三方组件进行封装,该函数调用第三方组件的适当函数。
  1. If you define a DTO (dtata transfer object) object:

    // Somewhere around an interface
    class ColumnSortItem
    {
        string Caption { get; set; }
        SortOrder Order { get; set; }
    }
    
    // Other places:
    void SortByColumns(IList<ColumnSortItem> pColumnSortItems);
    
  2. Tuples:

    void SortByColumns(IList<Tuple<string, SortOrder>> pColumnSortItems);
    

我并不是说元组始终是更好的选择,但请注意我们只需声明一定的顺序和项目结构即可。请注意,在这个具体的例子中,很明显哪些部分是元组的字符串部分,哪些部分是排序顺序部分。

附加说明:函数的实际调用:

  1. DTO

    controller.SortByColumns(new List<ColumnSortItem>() {
        new ColumnSortItem() { Caption = "Record", Order = SortOrder.Ascending },
        new ColumnSortItem() { Caption = "Description", Order = SortOrder.Ascending }
      });
    
  2. Tuple

    controller.SortByColumns(new List<Tuple<string, SortOrder>>() {
        new Tuple<string, SortOrder>("Record", SortOrder.Ascending),
        new Tuple<string, SortOrder>("Description", SortOrder.Ascending)
      });
    

请注意,如果元组仅包含两个元素,则可能使用KeyValuePair,但是KeyValuePair作为结构体会产生一些后果:http://www.dotnetperls.com/tuple-keyvaluepair - Csaba Toth

1

Tuple是一种轻量级的类,用于将多个项目组合在一起。它是定义新类的替代方案,每当您想要将两个项目组合在一起时使用。

当我想从单个方法返回多个项目,但无法使用ref或out参数时,我发现它非常有用。


1

看起来它是用于临时数据存储的,非常局限性的使用。这些情况下编写自己的类要么太耗费时间,要么因为数据的生命周期太短而不值得。


0

.NET Framework 4 引入了 System.Tuple 类,用于创建包含结构化数据的元组对象。它还提供了通用元组类来支持具有一到八个组件的元组。 以下是 C# 的示例:

var objTupe = new System.Tuple<string, string, double,long>"Mike","Anderson",29000,9999999999);
 Response.Write("Item1 : " + objTupe.Item1);
 Response.Write("<br/>Item2 : " + objTupe.Item2);
 Response.Write("<br/>Item3 : " + objTupe.Item3);
 Response.Write("<br/>Item4 : " + objTupe.Item4);

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