当前位置: 首页 > news >正文

C# 元组的用法

目录

一、值元组 System.ValueTuple

创建元组

命名元组元素

解构元组

元组的比较

元组的可变性

作为方法的返回值

二、传统元组 System.Tuple

Tuple.Create 方法

元组的不可变性

作为方法的返回值


一、值元组 System.ValueTuple

值类型,由 C# 7.0 引入,语法更简洁,性能更高。

创建元组

案例:

var tuple = (1, "Hello", 3.14);  // 创建一个元组,包含 int, string, double 三个类型的值
Console.WriteLine(tuple.Item1);  // 输出 1
Console.WriteLine(tuple.Item2);  // 输出 Hello
Console.WriteLine(tuple.Item3);  // 输出 3.14

在这里使用了 var,那么它原本的类型是怎么定义的呢?如下:

(int, string, double) tuple = (1, "Hello", 3.14);  // 创建一个元组,包含 int, string, double 三个类型的值
Console.WriteLine(tuple.Item1);  // 输出 1
Console.WriteLine(tuple.Item2);  // 输出 Hello
Console.WriteLine(tuple.Item3);  // 输出 3.14

这么看,使用 var 确实方便不少。

当然你也能把它用在字典中、List 中,等等。

案例:

var dictionary = new Dictionary<string, (int, float)>()
{{"a", (1, 1.5f) },{"b", (3, 5.8f) }
};
var list = new List<(int, string)>
{(2, "Bob"),(1, "Alice"),(3, "Charlie")
};

.NET8 中,还可以用在 switch 中,

案例:

public static string GetRole((int, string) person)
{switch (person){case (1, "Alice"):return "Developer";case (2, "Bob"):return "Manager";default:return "Unknown";}
}var person = (1, "Alice");
Console.WriteLine(GetRole(person));  // 输出 Developer

命名元组元素

你可以为元组中的元素指定名称,来提高可读性。

案例:

var tuple = (Id: 1, Name: "Alice", Age: 25);
Console.WriteLine(tuple.Id);    // 输出 1
Console.WriteLine(tuple.Name);  // 输出 Alice
Console.WriteLine(tuple.Age);   // 输出 25

这么写也是没有任何问题的,和 类[] 这种写法差不多

var data = new[] 
{new { Name = "Alice", Age = 30 },new { Name = "Bob", Age = 25 },new { Name = "Charlie", Age = 35 }
};

解构元组

C# 7.0 引入了元组的解构语法,你可以将元组的值直接赋给单独的变量。

案例1:

var (id, name, age) = (1, "Alice", 25);  // 解构元组
Console.WriteLine(id);    // 输出 1
Console.WriteLine(name);  // 输出 Alice
Console.WriteLine(age);   // 输出 25

直接使用 tuple.Item1,tuple.Item2  这种写法确实是方便一些,但自己定义它变量会看起来更加直观一些。

案例2:

// 定义一个包含两个元素的元组
(int id, string name) = (1, "Alice");// 访问元组的元素
Console.WriteLine(id);    // 输出:1
Console.WriteLine(name);  // 输出:Alice// 使用解构赋值
var (id2, name2) = (2, "Bob");
Console.WriteLine(id2);   // 输出:2
Console.WriteLine(name2); // 输出:Bob

元组的比较

它和普通的值类型一样,也是可以使用 == 来判断是否相同

案例:

var tuple1 = (1, "Alice");
var tuple2 = (1, "Alice");
var tuple3 = (2, "Bob");Console.WriteLine(tuple1 == tuple2);  // 输出 True
Console.WriteLine(tuple1 == tuple3);  // 输出 False

元组的可变性

这和后面的章节 System.Tuple 不可变性有所不同,System.ValueTuple 是可以修改元组的值。

案例:

var tuple = (1, "Alice", 25);  
tuple.Item1 = 30;

这段代码是不会报错的,并且能正确的输出它的值

Console.WriteLine(tuple.Item1); // 输出:30

作为方法的返回值

这和后面的章节 System.Tuple 用法差不多

案例:

public static (int, string) GetPersonInfo()
{return (42, "Alice");
}var result = GetPersonInfo();
Console.WriteLine($"Id: {result.Item1}, Name: {result.Item2}");

用在异步编程中也是一样的,我经常这么干

public static async Task<(int, string)> GetDataAsync()
{await Task.Delay(1000);  // 模拟异步操作return (42, "Hello");
}

二、传统元组 System.Tuple

引用类型,首次在 .NET Framework2.0 被引入,主要用于支持 F# 的元组类型。此时它并非通用语言运行时(CLR)的标准库类型,其他 .NET 语言(如 C#)无法直接使用,从 ​​.NET Framework 4.0​​ 开始,System.Tuple 被正式引入到 ​​Base Class Library (BCL)​​ 中,成为所有 .NET 语言通用的元组实现

Tuple.Create 方法

Tuple.Create 是一个静态方法,用于创建一个元组实例,它可以接受不同数量和类型的参数。通过 Tuple.Create 方法,C# 会自动推断每个元素的类型,因此你不需要显式地指定类型。

Tuple 最多能存储8个元素。

案例:

var tuple = Tuple.Create(true, "Hello", "World");
Console.WriteLine(tuple.Item1);  // 输出 true
Console.WriteLine(tuple.Item2);  // 输出 Hello
Console.WriteLine(tuple.Item3);  // 输出 World

这里使用 var 确实方便很多,不用每次去定义它原本的写法,比如

Tuple<bool, string, string> tuple = Tuple.Create(true, "Hello", "World");
Console.WriteLine(tuple.Item1);  // 输出 true
Console.WriteLine(tuple.Item2);  // 输出 Hello
Console.WriteLine(tuple.Item3);  // 输出 World

使用构造函数

var tuple = new ValueTuple<int, string>(1, "Hello");

但是,如果值是一些不确定的情况,也会报错,比如值为 null

如果非要传一个 null 的话也是可以的,只是要定义这个值原本的类型,比如:

var tuple = Tuple.Create<bool, string>(false, null);

这样子就不会报错了。

元组的不可变性

Tuple 类是不可变的,这意味着一旦创建了元组,其元素的值就不能修改

案例:

作为方法的返回值

如果想同时返回2个或者多个值,又不想去写一个类,元组是一个好的替代方案

internal class Test
{public Tuple<bool, string> hello(){return Tuple.Create(true, string.Empty);}
}

end

http://www.dtcms.com/a/334534.html

相关文章:

  • Nona生命之树作品TRO突袭,冻结名单曝光
  • Vue2.x核心技术与实战(一)
  • 摩搭api 实现
  • 025 理解文件系统
  • 多机编队——(6)解决机器人跟踪过程中mpc控制转圈问题
  • 第四章 Linux实用操作
  • OpenJDK 17的C1和C2编译器实现中,方法返回前插入安全点(Safepoint Poll)的机制
  • 【LeetCode题解】LeetCode 35. 搜索插入位置
  • [Linux] Linux逻辑卷管理
  • 知识点汇总linuxC高级 -2系统命令压缩与链接
  • RK3568 NPU RKNN(三):RKNN-ToolKit2模型构建与推理
  • 【LeetCode】算法详解#13 ---回文链表
  • Vue 3.5重磅更新:响应式Props解构,让组件开发更简洁高效
  • [Linux] Linux交换空间管理 Linux系统启动原理
  • 慧穗云开放平台 CDK 开票对接
  • echart中x的0位置出现柱子宽度被裁掉一部分的问题
  • 技术日记2025年08月16日
  • 基于FPGA的实时图像处理系统(1)——SDRAM回环测试
  • python---异常处理
  • Redis知识整理
  • 【论文笔记】STORYWRITER: A Multi-Agent Framework for Long Story Generation
  • 云服务平台主流架构的相关知识体系剖析
  • ABM和强化学习-2015年全国大学生数学建模竞赛B题
  • 安卓11 12系统修改定制化_____修改系统 解锁system分区 去除data加密 自由删减系统应用
  • JetPack系列教程(七):Palette——让你的APP色彩“飞”起来!
  • sql链接的url中serverTimezone的作用
  • 【大模型微调系列-04】 神经网络基础与小项目实战
  • windows环境下使用vscode以及相关插件搭建c/c++的编译,调试环境
  • GIMP:功能强大的跨平台图像处理软件
  • 嵌入式硬件篇---电容本质