元组 (ValueTuple)类型是值类型;元组元素是公共字段,可以使用任意数量的元素定义元组。Tuple类型像一个口袋,在出门前可以把所需的任何东西一股脑地放在里面。您可以将钥匙、驾驶证、便笺簿和钢笔放在口袋里,您的口袋是存放各种东西的收集箱。

到了c# 4.0 应当使用元组Tuple而不是使用输出参数,在任何时候都应避免使用ref/out传递参数,尤其对引用类型。

继承

Object-> ValueType ->Enum
Object-> ValueType ->struct 包括int float等简单值类型
Object-> ValueType ->ValueTuple
Object-> ValueType ->Nullable

元组项命名准则

务必对使用元组语法声明的所有变量使用驼峰式大小写。

****考虑对所有元组项名称使用 Pascal 命名法。

为什么要使用元组?

有时,可能会发现,将数据元素组合在一起非常有用。例如,假设要处理国家/地区相关信息,如 2017 年世界上最贫穷的国家/地区马拉维。它的首都是利隆圭,人均国内生产总值 (GDP) 为 226.50 美元。显然,可以为此类数据声明一个类,但它并不是真正典型的名词/对象。它似乎更像是一组相关数据,而不是对象。当然,若要设置 Country 对象(举个例子),所含数据远不止 Name、Capital 和 GDP per capita 这些属性。也可以将每个数据元素存储在各个变量中,但这样做的结果是,数据元素相互没有任何关联。除了变量名称可能共用后缀或前缀之外,226.50 美元与马拉维将无任何关联。另一种方法是,将所有数据组合到一个字符串中。不过,这样做的缺点是,必须先分析各个数据元素,然后才能分别处理这些元素。最后一种方法是创建匿名类型,但这样做同样有局限性。其实,元组足以完全替代匿名类型.-----Mark Michaelis

一、元组声明和分配示例代码

   //元组写法1通过example2.Item来引用
var example1 = (1,2,3,4,5,"23",1,2,3,1,5,6,2,3);
Console.WriteLine(example1.Item10); //元组写法2, 通过example3.变量名引用
var example2 = (exa1:1, exa2: 2,3,4,5,6);
Console.WriteLine(example2.exa2); //元组写法3, 通过example3.变量名引用 左侧不允许弃元
(int age, string name) example3 = (3, "Dog3");
Console.WriteLine(example3.name); //元组写法4 相当于批量赋值 可以单独使用 变量 左侧不允许弃元
(string sr, bool sb, int sc) = ("4sr",true,1);
Console.WriteLine(sr); //元组写法5 元组元素是公共字段 所以可以单独引用
var (exa51, exa52) = ("51f", 5.1);
Console.WriteLine(exa51); //元组写法6 元组元素是公共字段 所以可以单独引用
var example6 = ("post office", 6.3);
(string destination, double distance) = example6;
Console.WriteLine(distance); //元组写法7 将元组分配到各个已预声明的变量中。
var exa71 = string.Empty;
var exa72 = 0.0;
var example7 = ("post office", 7.2);
(exa71, exa72) = example7;
Console.WriteLine(exa72); //元组写法8 将元组分配到各个已预声明的变量中。 string country;
string capital;
double gdpPerCapita;
(country, capital, gdpPerCapita) =("Malawi", "Lilongwe", 226.50);
System.Console.WriteLine( $"The poorest country in the world in 2017 was {country}, {capital}: {gdpPerCapita}"); //元组写法9 弃元 将未命名的元组分配到一个隐式类型化变量中,
var countrInfo = ("Malawi", "Lilongwe", 226.50); (string name, _, double gdpPerCapit) = countrInfo;
Console.WriteLine(gdpPerCapit);
//C#10混合定义
int y = 0;
(var x, y, var z) = (1, 2, 3);
部分内容来源:https://docs.microsoft.com/zh-cn/archive/msdn-magazine/2017/august/essential-net-csharp-7-0-tuples-explained

二、元组赋值和析构

C# 支持满足以下两个条件的元组类型之间的赋值:
            1、两个元组类型有相同数量的元素
            2、对于每个元组位置, 右侧元组元素的类型与左侧相应的元组元素的类型相同或可以隐式转换为左侧相应的元
            组元素的类型

             (int, double) t1 = (17, 3.14);
(double First, double Second) t2 = (0.0, 1.0); t2 = t1; Console.WriteLine(t2);

三、比较运算符!= 和== 从 C# 7.3 开始支持

元组赋值和元组相等比较不会考虑字段名称。

同时满足以下两个条件时,两个元组可比较:
两个元组具有相同数量的元素。 例如,如果 t1 和 t2 具有不同数目的元素, t1 != t2 则不会进行编译。
对于每个元组位置,可以使用 == 和 != 运算符对左右侧元组操作数中的相应元素进行比较。 例如,
(1, (2, 3)) == ((1, 2), 3) 不会进行编译,因为 1 不可与 (1, 2) 比较。

(int a, byte b) left = (5, 10);
(long a, int b) right = (5, 10);
Console.WriteLine(left == right); // output: True
Console.WriteLine(left != right); // output: False
var t1 = (A: 5, B: 10);
var t2 = (B: 5, A: 10);
Console.WriteLine(t1 == t2); // output: True
Console.WriteLine(t1 != t2); // output: False

== 和 != 运算符将以短路方式对元组进行比较。 也就是说,一旦遇见一对不相等的元素或达到元组的末尾,操
作将立即停止。 但是,在进行任何比较之前,将对所有元组元素进行计算,如以下示例所示:

Console.WriteLine((Display(1), Display(2)) == (Display(3), Display(4)));
int Display(int s)
{
Console.WriteLine(s);
return s;
}
// Output:
// 1
// 2
// 3
// 4
// False

四、元组作为 out 参数
通常,你会将具有 out 参数的方法重构为返回元组的方法。 但是,在某些情况下, out 参数可以是元组类型。
下面的示例演示了如何将元组作为 out 参数使用:

var limitsLookup = new Dictionary<int, (int Min, int Max)>()
{
[2] = (4, 10),
[4] = (10, 20),
[6] = (0, 23)
};
if (limitsLookup.TryGetValue(4, out (int Min, int Max) limits))
{
Console.WriteLine($"Found limits: min is {limits.Min}, max is {limits.Max}");
}
// Output:
// Found limits: min is 10, max is 20

 五、元组与 System.Tuple
System.ValueTuple 类型支持的 C# 元组不同于 System.Tuple 类型表示的元组。 主要区别如下:
ValueTuple 类型是值类型。 Tuple 类型是引用类型。
ValueTuple 类型是可变的。 Tuple 类型是不可变的。
ValueTuple 类型的数据成员是字段。 Tuple 类型的数据成员是属性。

六、元组结构


 //元组写法9  弃元 将未命名的元组分配到一个隐式类型化变量中,
var countrInfo = ("Malawi", "Lilongwe", 226.50);
(string name, _, double gdpPerCapit) = countrInfo;

上面代码是不是很惊奇,反正我第一次看到时特别惊讶,也感觉特别有意思,那么这到底怎么实现的呢,我查看一下iL代码:

原来只是在类中添加一个解构函数(Deconstruct)就可以,解构参数方法名称必须是Deconstruct,返回值必须是void,参数列表必须是out

  public void Deconstruct(out int x, out int y) => (x, y) = (X, Y);
 

C# 9.0元组 (ValueTuple)详细解说的更多相关文章

  1. Swift3.0 元组 (tuples)

    //元组 //不需要的元素用 _ 标记 let (name,age,_) = (","男") print(name,age) //通过下标访问特定的元素 let stud ...

  2. Tuple元组 、 ValueTuple 值元组详解

    Tuple元组 Tuple是C# 4.0时出的新特性,.Net Framework 4.0以上版本可用. 元组是一种数据结构,具有特定数量和元素序列,与数组不同,元祖中的元素可以不同的数据类型.比如设 ...

  3. C#7.0中的解构功能---Deconstruct

    解构元组 C#7.0新增了诸多功能,其中有一项是新元组(ValueTuple),它允许我们可以返回多个值,并且配合解构能更加方便的进行工作,如下面例子 static void Main(string[ ...

  4. Tuple和 ValueTuple

    这个类型还是学习C#7.0的语法在看到的,这边单独拿来学习下. 学习地址: https://docs.microsoft.com/zh-cn/dotnet/csharp/tuples https:// ...

  5. C# 7.0 新增功能&结合微软简化理解

    C# 7.0更新时间为2019.2左右 C# 7.0 ~ 7.3 分别需要VS2017 与 .NET Core 1.0. .NET Core 2.0 SDK..NET Core 2.1 SDK,需要在 ...

  6. Python基础-列表_元组_字典_集合

    本节内容 列表.元组操作 字符串操作 字典操作 集合操作 文件操作 字符编码与转码 1. 列表.元组操作 列表是我们最以后最常用的数据类型之一,通过列表可以对数据实现最方便的存储.修改等操作 定义列表 ...

  7. Swift基础语法 、 元组(Tuple)

    字符串的使用 1.1 问题 Swift的String和Character类型提供了一个快速的,兼容Unicode的方式来处理代码中的文本信息.创建和操作字符串的语法与C语言中字符串类似.本案例将学习如 ...

  8. python笔记之列表与元组函数和方法使用举例

    在学习列表之前先了解了raw_input和input的区别:(仅适用于版本2,版本3中raw_input和input合并,没有raw_input) input的语法为:input("str& ...

  9. Python/零起点(一、数字及元组)

    Python/零起点(一.数字及元组) int整型 int()强行转换成整型数据类型 int整型是不可变,且是不可迭代的对象 一.整型数字用二进制位数表示案例: age=7 #设定一个数字赋值给age ...

随机推荐

  1. uniapp微信小程序保存base64格式图片的方法

    uniapp保存base64格式图片的方法首先第一要先获取用户的权限 saveAlbum(){//获取权限保存相册 uni.getSetting({//获取用户的当前设置 success:(res)= ...

  2. gin中的SecureJSON 防止 json 劫持

    使用 SecureJSON 防止 json 劫持.如果给定的结构是数组值或map,则默认预置 "while(1)," 到响应体. package main import ( &qu ...

  3. 【Vue源码学习】响应式原理探秘

    最近准备开启Vue的源码学习,并且每一个Vue的重要知识点都会记录下来.我们知道Vue的核心理念是数据驱动视图,所有操作都只需要在数据层做处理,不必关心视图层的操作.这里先来学习Vue的响应式原理,V ...

  4. linux区分atime,ctime and mtime

  5. 社交网络分析的 R 基础:(一)初探 R 语言

    写在前面 3 年的硕士生涯一转眼就过去了,和社交网络也打了很长时间交道.最近突然想给自己挖个坑,想给这 3 年写个总结,画上一个句号.回想当时学习 R 语言时也是非常戏剧性的,开始科研生活时到处发邮件 ...

  6. 如何将EDI报文转换为CSV格式文件?

    如果您对EDI项目实施有一定的了解,想必您一定知道,在正式开始EDI项目实施之前,都会有EDI顾问与您接洽,沟通EDI项目需求.其中,会包含EDI通信双方使用哪种传输协议,传输的报文是符合什么标准的, ...

  7. Android文件的权限概念

    //通过context对象获取一个私有目录的文件读取流  /data/data/packagename/files/userinfoi.txt   FileInputStream fileInputS ...

  8. 使用df -h命令查看磁盘空间使用率不算高,还有很多空余空间,但是创建文件或写入数据时一直报错磁盘写满

    关于磁盘空间中索引节点爆满的问题还是挺多的,借此跟大家分享一下: 一.发现问题 在公司一台配置较低的Linux服务器(内存.硬盘比较小)的/data分区内创建文件时,系统提示磁盘空间不足,用df -h ...

  9. Plist存储

  10. js判断当前浏览设备

    前端开发经常遇到需要判断用户的浏览设备,是pc端还是移动端,移动端使用的是什么手机系统?android.ios.ipad.windows phone等等,有时候还需要知道用户浏览页面是在微信中打开还是 ...