C# Tuple、ValueTuple

server/2024/9/22 16:50:17/

栏目总目录


Tuple

Tuple是C# 4.0引入的一个新特性,主要用于存储一个固定数量的元素序列,且这些元素可以具有不同的类型。Tuple是一种轻量级的数据结构,非常适合用于临时存储数据,而无需定义完整的类或结构体。

优点

  • 简便性:可以快速创建一个包含多个不同类型数据的对象,而无需定义新的类或结构体。
  • 灵活性:元素数量和类型在编译时确定,但可以在不同上下文中重复使用不同元素的Tuple。

缺点

  • 性能:作为引用类型,Tuple在堆上分配内存,可能导致更高的内存使用率和更频繁的垃圾回收。
  • 可读性和维护性:元素通过Item1Item2等方式访问,缺乏语义化名称,导致代码可读性差,且难以维护。
  • 限制:最多只能包含8个元素,对于需要更多元素的情况,需要通过嵌套Tuple来实现,这进一步增加了复杂性。

应用场景

  • 临时存储数据,例如在多个方法的调用中传递数据。
  • 返回值包含多个值时,可以使用Tuple代替多个out参数。

示例代码

// 使用构造函数创建Tuple
var testTuple6 = new Tuple<int, int, int, int, int, int>(1, 2, 3, 4, 5, 6);
Console.WriteLine($"Item 1: {testTuple6.Item1}, Item 6: {testTuple6.Item6}");// 使用Tuple的静态方法Create创建Tuple
var testTuple8 = Tuple.Create<int, int, int, int, int, int, int, int>(1, 2, 3, 4, 5, 6, 7, 8);
// 注意:当元素超过7个时,第八个元素实际上是一个新的Tuple
// 要访问第八个元素,需要这样:
Console.WriteLine($"Item 8: {testTuple8.Rest.Item1}");// 创建一个表示学生信息的Tuple
var studentInfo = Tuple.Create<string, int, uint>("Bob", 28, 175);
Console.WriteLine($"Student Information: Name [{studentInfo.Item1}], Age [{studentInfo.Item2}], Height [{studentInfo.Item3}]");

ValueTuple

值类型特性

  • ValueTuple是值类型(struct),在栈上分配内存(局部使用时),或在堆上(作为对象成员时)。
  • 减少了内存分配和垃圾回收的开销,提升了性能。

可变性与命名元素

  • System.Tuple不同,ValueTuple的元素在创建后是可以修改的。
  • 在C# 7.3及更高版本中,支持命名元素,使代码更直观易懂。
  • 命名元素在编译时提供强大支持,尽管运行时不会转换为实际属性或字段。

简洁语法与解构赋值

  • 创建ValueTuple的语法简洁,直接使用(和)包含多个值。
  • 支持解构赋值,允许从ValueTuple中直接提取值到变量中。
  • 简化了代码编写,提高了开发效率。

处理多个返回值

  • 允许方法返回一个包含多个值的ValueTuple,避免了out参数或专门类的使用。
  • 使得方法调用和返回过程更加简洁和清晰。

应用场景

  • 适用于返回多个值、临时数据组合和数据交换等多种场景。
  • 为处理包含多个值的数据结构提供了轻量级且高效的解决方案。

示例代码

using System;namespace ValueTupleDemo
{class Program{// 定义一个返回ValueTuple的函数static (string Name, int Age, uint Height) GetStudentInfo(string name){return ("Bob", 28, 175u);}static void Main(string[] args){// 使用新的返回语法调用函数var (name, age, height) = GetStudentInfo("Bob");// 传统的访问方式仍然有效var studentInfo = GetStudentInfo("Bob");Console.WriteLine($"Student Information: Name [{studentInfo.Name}], Age [{studentInfo.Age}], Height [{studentInfo.Height}]");// 解构赋值到临时变量(var tempName, var tempAge, var tempHeight) = GetStudentInfo("Bob");Console.WriteLine($"Temporary Student Information: Name [{tempName}], Age [{tempAge}], Height [{tempHeight}]");// 忽略不需要的元素var (_, ageOnly, _) = GetStudentInfo("Bob");Console.WriteLine($"Age Only: [{ageOnly}]");// 嵌套ValueTuplevar complexTuple = (1, (2, 3), 4);Console.WriteLine($"Complex Tuple: ({complexTuple.Item1}, ({complexTuple.Item2.Item1}, {complexTuple.Item2.Item2}), {complexTuple.Item3})");// 使用C# 7.3及以上版本的命名特性(需编译器支持)// 注意:这里仅为示例,实际编译器可能需要特定版本或配置来支持static (string firstName, string lastName) GetName(string fullName){var parts = fullName.Split(' ');return (parts[0], parts[1]);}var (firstName, lastName) = GetName("John Doe");Console.WriteLine($"First Name: {firstName}, Last Name: {lastName}");}}
}

注意

  • 嵌套ValueTuple的使用(如var complexTuple = (1, (2, 3), 4);)展示了如何通过嵌套来扩展元组的能力。
  • 示例中的命名特性(如static (string firstName, string lastName) GetName(string fullName))在C# 7.3及更高版本中可用,并需要编译器支持。这个特性允许你为ValueTuple的每个元素指定有意义的名称,而不仅仅是使用Item1Item2等。
  • 解构赋值(如var (name, age, height) = GetStudentInfo("Bob");)提供了从ValueTuple中提取数据的便捷方式。

总结

Tuple提供了一种快速、简便的方式来创建包含多个元素的数据结构,但其缺点也不容忽视。在C# 7.0及更高版本中,ValueTuple作为Tuple的改进版,提供了更好的性能和更灵活的使用方式,是处理多个返回值或临时数据结构时的更好选择。


http://www.ppmy.cn/server/118413.html

相关文章

Android 后台服务之Persistent 属性

在 Android 开发中,有时我们需要后台服务持续运行,以保持应用的某些功能。例如,音乐播放器需要在后台播放音乐,或者健康应用需要持续跟踪用户的运动数据。后台服务是 Android 中的一种组件,它不与用户界面交互,能够在后台执行长时间运行的任务。由于 Android 系统的资源管…

【Linux】09.Linux 下的调试器——gdb/cgdb

一、gdb/cgdb的认识 我们在VS上调试时都是使用Debug版本的&#xff0c;但是在Linux下gcc/g默认生成的是Relaese版本&#xff0c;我们想要进行调试就要用-g选项生成Debug版本的程序。但是Linux下的gdb是一种命令行调试工具&#xff0c;因此就有了cgdb为我们提供可视化的调试界面…

【算法】差分思想:强大的算法技巧

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &#x1f4e2;本文由 JohnKi 原创&#xff0c;首发于 CSDN&#x1f649; &#x1f4e2;未来很长&#…

从底层原理上解释 clickhouse 保证完全的幂等性

在分布式系统中&#xff0c;幂等性是指某个操作被多次执行&#xff0c;其效果和结果应该和执行一次相同。ClickHouse作为一个高效的OLAP数据库&#xff0c;在其底层架构和查询引擎中&#xff0c;通过多个机制和策略来确保操作的幂等性。具体来说&#xff0c;ClickHouse的幂等性…

【设计模式-外观】

这里写自定义目录标题 定义UML图角色作用代码使用场景 定义 为子系统中一组相关接口提供一致界面&#xff0c;定义一个高级接口&#xff0c;使得子系统更加容易使用。 UML图 角色作用 外观&#xff08;Facade&#xff09;角色&#xff1a;这是外观模式的核心&#xff0c;它知…

fmql之ubuntu移植

官方资料&#xff1a;ubuntu18的压缩包 目的&#xff1a;放到SD卡中启动ubuntu&#xff08;官方是放在emmc中&#xff09; 教程&#xff1a;99_FMQL45_大黄蜂开发板跑ubuntu18.04.docx 所需文件 其中&#xff0c;format_emmc_ext4.txt对emmc的分区是512M&#xff08;放上述文…

算法打卡:第九章 动态规划part12

今日收获&#xff1a;不同的子序列&#xff0c;两个字符串的删除操作&#xff0c;编辑距离 1. 不同的子序列 题目链接&#xff1a;115. 不同的子序列 - 力扣&#xff08;LeetCode&#xff09; 思路&#xff1a; &#xff08;1&#xff09;dp数组表示两个字符串 i-1,j-1位置…

Linux审计系统软件auditd简介

Linux审计系统软件auditd是一个强大的工具&#xff0c;用于监控和记录安全相关的信息。它最初是基于Linux 2.6.11.12版本内核开发的&#xff0c;主要的审计机制代码位于kernel/audit.c和kernel/auditsc.c中[^4]。auditd可以记录系统调用和文件访问等事件&#xff0c;帮助系统管…