佳佳的博客
Menu
首页
《.NET Core 实战》 [No.201~207] 元组
Posted by
佳佳
on 2020-03-20
IT
C#
.NET Core
《.NET Core 实战》
读书笔记
<!-- # 《.NET Core 实战》 [No.201~207] 元组 --> <!-- dotnet-core-tuple --> 元组(`Tuple`)类型很早就有了,但在低于 *7.0* 的版本中,只能通过 *Item1*、*Item2* 这样的属性来访问,没有实际的语义。 从 [7.0][1] 开始元组增加了语义上的支持等功能,更加易于使用。实际上这里说的元组已经不是指之前的 `Tuple` 类型了,而是新增的 **值元组** `ValueTuple` 类型。 先说一下旧的元组类型。 `Tuple` 可以通过 `new` 关键字 或者 `Tuple.Create()` 方法 创建,只能通过 `Item*` 属性获取元素值,而且是只读属性,无法修改。 ```csharp var namelessLetters = new Tuple<string, string>("a", "b"); namelessLetters = Tuple.Create("a", "b"); Console.WriteLine($"Item1:{namelessLetters.Item1}, Item2:{namelessLetters.Item2}"); ``` *7.0* 及之后的几个小版本中对元组添加了很多特性; - [7.0][1] - 增加了语义上的支持(可以对元素命名) - 支持解构(*Deconstruct*) - 解构时支持弃元(`_`) - [7.1][2] - 元素名支持推断 - [7.3][3] - 支持 `==` 和 `!=` 操作符 新的元组类型 `ValueTuple` 是值类型,不需要分配堆内存,效率优于 `Tuple` 。 此外,`ValueTuple` 的元素初始化以后是可以修改的。 `ValueTuple` 也可以和 `Tuple` 类似使用 *new* 关键字 或 `ValueTuple.Create()` 方法 初始化。不过推荐使用 C# 新语法来初始化,语法上更简洁易懂。 ```csharp var namelessLetters = ("a", "b"); namelessLetters.Item1 = "A"; Console.WriteLine($"Item1:{namelessLetters.Item1}, Item2:{namelessLetters.Item2}"); // Item1:A, Item2:b ``` `ValueTuple` 支持对元素命名,可以通过如下三种方式声明。 ```csharp (string Alpha, string Beta) namedLetters = ("a", "b"); ``` ```csharp var namedLetters = (Alpha: "a", Beta: "b"); ``` 这第三种是通过 *7.1* 中新增的推断功能来实现的,需要将项目的语言版本指定为 *7.1* 或以上。 ```csharp var Alpha = "a"; var Beta = "b"; var namedLetters = ( Alpha, Beta ); ``` 可以通过指定的元素名获取或修改元素值,同时也仍旧支持使用 `Item*` 的方式获取或修改元素值。 ```csharp namedLetters.Alpha = "A"; Console.WriteLine($"Alpha:{namedLetters.Alpha}, Beta:{namedLetters.Beta}"); // Alpha:A, Beta:b Console.WriteLine($"Item1:{namedLetters.Item1}, Item2:{namedLetters.Item2}"); // Item1:A, Item2:b ``` 验证下上面定义的 *namedLetters* 变量的类型。 ```csharp Console.WriteLine($"The type of namedLeeters:{namedLetters.GetType()}"); // The type of namedLeeters:System.ValueTuple`2[System.String,System.String] ``` `ValueTuple` 支持解构。解构之后,元组中的字段可以作为普通变量来使用。 ```csharp (string alpha, string beta) = ("a", "b"); Console.WriteLine($"alpha:{alpha}, beta:{beta}"); // alpha:a, beta:b ``` 解构更常用于的是解构方法返回值中的元组。 ```csharp (string Alpha, string Beta) GetLetters() { return ("a", "b"); } ``` ```csharp (string alpha, string beta) = GetLetters(); Console.WriteLine($"alpha:{alpha}, beta:{beta}"); // alpha:a, beta:b ``` 当然也可以直接将方法的返回值赋给一个元组变量。 ```csharp var letters = GetLetters(); Console.WriteLine($"letters.Alpha:{letters.Alpha}, letters.Beta:{letters.Beta}"); // letters.Alpha:a, letters.Beta:b ``` 另外,自定义类型也可以支持解构,只需要实现 *Deconstruct* 方法。示例如下: ```csharp public class Point { public Point(double x, double y) => (X, Y) = (x, y); public double X { get; } public double Y { get; } public void Deconstruct(out double x, out double y) => (x, y) = (X, Y); } ``` <!-- 链接 --> [1]: https://www.liujiajia.me/2017/4/14/dotnet-csharp-whats-new-in-7-0 (C# 7.0 中的新增功能) [2]: https://www.liujiajia.me/2019/11/4/dotnet-csharp-whats-new-in-7-1 (C# 7.1 中的新增功能) [3]: https://www.liujiajia.me/2019/11/7/dotnet-csharp-whats-new-in-7-3 (C# 7.3 中的新增功能) --- > 购买本书 => [《.NET Core实战:手把手教你掌握380个精彩案例》][10] -- *周家安* 著 --- [10]:https://union-click.jd.com/jdc?e=&p=AyIGZRhaEwAQBFUZXBIyEgRSEl0QCxc3EUQDS10iXhBeGlcJDBkNXg9JHU4YDk5ER1xOGRNLGEEcVV8BXURFUFdfC0RVU1JRUy1OVxUBFQ5THlIQMm1AEkRdb11GZyNTK0BBZwYIbylWcHILWStaJQITBlYbXB0LFQJlK1sSMkBpja3tzaejG4Gx1MCKhTdUK1sRCxQBVxtTEQIQBlwrXBULIloNXwZBXUReEStrJQEiN2UbaxYyUGlUG1kUBhcGUBILQgUXDlMeUkBVRlUBS10XBkIABhkJRzIQBlQfUg%3D%3D (《.NET Core实战:手把手教你掌握380个精彩案例》)
版权声明:原创文章,未经允许不得转载。
https://www.liujiajia.me/2020/3/20/dotnet-core-tuple
“Buy me a nongfu spring”
« 《.NET Core 实战》 [No.232] 使用并行 LINQ
《.NET Core 实战》 [No.200] 跨线程访问 BlockingCollection 集合 »
昵称
*
电子邮箱
*
回复内容
*
(回复审核后才会显示)
提交
目录
AUTHOR
刘佳佳
江苏 - 苏州
软件工程师
梦嘉集团