Tuple的意义

  • Tuple提供了简单的方式来存储一组数据
  • 使用Tuple的主要目的是从方法安全的返回多个值,而且无需使用out参数
  • C#7的Tuple主要是依赖于一组支撑它的struct,叫做System.ValueTuple<>

创建Tuple

  • 创建Tuple字面值最简单的方式就是在小括号里列出所有的值。
  • 通过XX.Item1,XX.Item2来引用tuple里面的未命名元素。
    • 未命名图片.png
  • Tuple是值类型,其元素是可变的(可读写)
    • 未命名图片.png
  • 你可以明确的指定Tuple的类型
    • 只需要在小括号里列出每个元素的类型即可
      • 未命名图片.png
  • 可以从方法返回Tuple类型
    • 未命名图片.png
  • Tuple可以和泛型很好的共存
    • 未命名图片.png

为Tuple元素命名

  • 在创建Tuple字面值的时候,你可以给元素一个有意义的名字。
  • 在指定Tuple类型的时候,也可以给元素起名。
    • 未命名图片.png
  • 仍然可以通过Item1,Item2来引用元素(VS没有智能提示)
    • 未命名图片.png
  • 如果两个Tuple的元素类型、顺序都一致(元素名没关系),那么两个Tuple的类型就是兼容的。
    • 未命名图片.png

类型擦除

  • C#使用了一组现存的泛型struct来处理Tuple
    • public struct ValueTuple
    • public struct ValueTuple
    • public struct ValueTuple
    • 每个ValueTuple<>struct都有 Item1,Item2…等字段
  • 所以(string,int)就是ValueTuple的一个别名而已
    • 在底层类型里命名的元素没有对应的属性名。
    • 元素名仅仅存在于源代码和编译器的想象中。
  • 在运行时,大部分元素名都会消失
  • 针对返回命名Tuple的方法/属性,编译器会通过在成员的返回类型上使用TupleElementNamesAttribute,来释放出元素名。
    • 运行在其它Assembly里面调用方法时可以使用命名元素。

ValueTuple.Create

可以使用ValueTuple(非泛型)类型上的工厂方法来创建Tuple
命名元素不可以使用这种方式来创建,因为元素命名依赖于编译器的一些操作
未命名图片.png

Deconstructing Tuples

Tuple隐式的支持Deconstruction模式,你可以很简单的将Tuple deconstruct为多个变量
未命名图片.png
不要和Tuple混淆了,
带命名的是Tuple,不带的是解构器(Deconstruction)

相等性比较

ValueTuple<>也重写了Equals方法,让比较更有意义
通过例子可以看出,Tuple可以作为Dictionary的Key
Tuple也实现了IComparable接口,所有Tuple也可以作为排序的Key
未命名图片.png

System.Tuple Classes

System命名空间下还有一组泛型类叫做Tuple(而不是ValueTuple)
.NET Framework 4.0引入的class
而ValueTuple是struct