首页 > 编程语言 >C# 中 Tuple 与 ValueTuples 之间的区别

C# 中 Tuple 与 ValueTuples 之间的区别

时间:2024-08-15 09:24:34浏览次数:10  
标签:Tuple C# System 元组 ValueTuples Id ValueTuple IsActive

在 C# 中,元组和值元组都用于在单个变量中存储多个值。但它们在语法、功能和性能方面存在一些关键差异。

一.Tuples(元组)

元组是一种引用类型,长期以来一直是 .NET 的一部分。它们是使用 System.Tuple 类创建的。

例子

using System;
class Program
{
    static void Main()
    {
        // 创建一个 Tuple 元组
        Tuple<int, string, bool> tupleExample = new Tuple<int, string, bool>(1, "Hello", true);

        // 访问 Tuple 元素
        Console.WriteLine($"Item1: {tupleExample.Item1}, Item2: {tupleExample.Item2}, Item3: {tupleExample.Item3}");
    }
}

二.ValueTuples(值元组)

ValueTuples 是最近添加的,是 C# 7.0 引入的值类型。与旧版 System.Tuple 相比,它们更轻量级,性能更好。ValueTuple 是使用 System.ValueTuple 结构创建的。

例子

class Program
{
    static void Main()
    {
        // 创建一个 ValueTuple
        (int, string, bool) valueTuple = (1, "Hello", true);

        // 访问 ValueTuple 的元素
        Console.WriteLine($"Item1: {valueTuple.Item1}, Item2: {valueTuple.Item2}, Item3: {valueTuple.Item3}");

        // 为 ValueTuple 的元素分配名称
        var namedValueTuple = (Id: 1, Message: "Hello", IsActive: true);
        Console.WriteLine($"Id: {namedValueTuple.Id}, Message: {namedValueTuple.Message}, IsActive: {namedValueTuple.IsActive}");
    }
}

三.主要区别

  1. Tuples(元组):引用类型(System.Tuple)。
  • ValueTuples(值元组):值类型(System.ValueTuple)。
  1. Tuples(元组):由于引用类型和堆分配而速度较慢。
  • ValueTuples(值元组):由于值类型和堆栈分配而速度更快。
  1. Tuples(元组):需要一个新的关键字。
  • ValueTuples(值元组):简洁,更易读,可以使用解构和命名元素。
  1. Tuples(元组):不可变值,创建后无法更改。
  • ValueTuples(值元组):可变值可以在创建后更改。

四.实际场景

在从 SQL Server 数据库检索数据的实际场景中,使用Tuple 和 ValueTuple。

1.执行以下 SQL Server 脚本

CREATE TABLE EmployeesDetails (
    Id INT PRIMARY KEY,
    Name NVARCHAR(100),
    IsActive BIT
);

INSERT INTO EmployeesDetails (Id, Name, IsActive)
VALUES (1, 'Alice', 1);

INSERT INTO EmployeesDetails (Id, Name, IsActive)
VALUES (2, 'Bob', 0);

2.查询

3.创建如下类

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;

namespace WpfApp2
{
    public class TupleExamples
    {
        static string connectionString = "Server=DESKTOP-JNM9BF1\\OMatrixtechSERVER;Database=Demo;User Id=sa;Password=1234;"; // 设置数据库连接字符串
        static string query = "SELECT Id, Name, IsActive FROM EmployeesDetails"; // 定义查询语句,用于从 EmployeesDetails 表中获取数据

        // 方法:从数据库中检索员工详情,并以 Tuple 的形式返回
        public static Tuple<int, string, bool> GetEmployeeTupleResult()
        {
            using (SqlConnection connection = new SqlConnection(connectionString)) // 使用连接字符串创建数据库连接
            {
                SqlCommand command = new SqlCommand(query, connection); // 创建 SqlCommand 对象,执行查询
                connection.Open(); // 打开数据库连接
                SqlDataReader reader = command.ExecuteReader(); // 执行查询并返回 SqlDataReader 对象

                if (reader.Read()) // 如果有数据返回
                {
                    return new Tuple<int, string, bool>( // 创建一个 Tuple 对象并返回,包含三个字段的值
                        reader.GetInt32(0), // 从结果中获取第一个字段(Id)
                        reader.GetString(1), // 从结果中获取第二个字段(Name)
                        reader.GetBoolean(2) // 从结果中获取第三个字段(IsActive)
                    );
                }
            }
            return null; // 如果没有数据返回,返回 null
        }

        // 方法:从数据库中检索员工详情,并以 ValueTuple 的形式返回
        public static (int Id, string Name, bool IsActive) GetEmployeeValueTupleResult()
        {
            using (SqlConnection connection = new SqlConnection(connectionString)) // 使用连接字符串创建数据库连接
            {
                SqlCommand command = new SqlCommand(query, connection); // 创建 SqlCommand 对象,执行查询
                connection.Open(); // 打开数据库连接
                SqlDataReader reader = command.ExecuteReader(); // 执行查询并返回 SqlDataReader 对象

                if (reader.Read()) // 如果有数据返回
                {
                    return ( // 返回一个命名的 ValueTuple,包含三个字段的值
                        reader.GetInt32(0), // 从结果中获取第一个字段(Id)
                        reader.GetString(1), // 从结果中获取第二个字段(Name)
                        reader.GetBoolean(2) // 从结果中获取第三个字段(IsActive)
                    );
                }
            }
            return (0, null, false); // 如果没有数据返回,返回一个默认的 ValueTuple
        }
    }
}

// 示例:如何调用上述方法以检索并显示员工详情
private void ValueTuple_Click(object sender, RoutedEventArgs e) // 按钮点击事件处理程序
{
    Tuple<int, string, bool> tupleValue = TupleExamples.GetEmployeeTupleResult(); // 调用 GetEmployeeTupleResult 方法,并将结果存储在 tupleValue 变量中
    (int Id, string Name, bool IsActive) = TupleExamples.GetEmployeeValueTupleResult(); // 调用 GetEmployeeValueTupleResult 方法,并将 ValueTuple 的结果解构到相应的变量中
}

五.结论

ValueTuple 是大多数当代 C# 应用程序的首选,因为它具有性能优势和更简洁的语法。虽然传统 Tuple 仍然可以访问和使用,但除非需要与旧版 .NET 兼容,否则它通常不那么受欢迎。

标签:Tuple,C#,System,元组,ValueTuples,Id,ValueTuple,IsActive
From: https://blog.csdn.net/xiefeng240601/article/details/141065094

相关文章

  • 【C语言】sizeof 和 strlen
    sizeof和strlen的对比sizeof在学习操作符的时候,我们学习了sizeof,sizeof计算变量所占内存内存空间大小的,单位是字节。如果操作数是类型的话,计算的是使用类型创建的变量所占内存空间的大小。sizeof只关注占用内存空间的大小,不在乎内存中存放什么数据。比如:#include......
  • Dockerfile
    使用Dockerfile可以允许用户创建自定义的镜像。Dockerfile基本结构Dockerfile由一行行命令语句组成,并且支持以#开头的注释行。一般的,Dockerfile分为四部分:基础镜像信息、维护者信息、镜像操作指令和容器启动时执行指令。例如#Thisdockerfileusestheubunt......
  • PHP转Go系列 | ThinkPHP与Gin框架之打造基于WebSocket技术的消息推送中心
    大家好,我是码农先森。在早些年前客户端想要实时获取到最新消息,都是使用定时长轮询的方式,不断的从服务器上获取数据,这种粗暴的骚操作实属不雅。不过现如今我也还见有人还在一些场景下使用,比如在PC端扫描二维码,然后使用长轮询的方式从服务端获取最新的扫码信息,来判断用户是否已经......
  • Java 中的线程本地存储(ThreadLocal)机制介绍
    Java中的ThreadLocal是一个用于实现线程本地存储(ThreadLocalStorage,TLS)的机制。它可以为每个线程提供独立的变量副本,使得一个线程中的变量不受其他线程中的变量的影响。ThreadLocal通常用于在多线程环境下避免线程之间共享数据,从而实现线程安全。一、基本用法ThreadLoca......
  • canvas实现手动绘制矩形
    开场白虽然在实际的开发中我们很少去绘制流程图就算需要,我们也会通过第3方插件去实现下面我们来简单实现流程图中很小的一部分手动绘制矩形绘制一个矩形的思路我们这里绘制矩形会使用到canvas.strokeRect(x,y,w,h)方法绘制一个描边矩形x:矩形起点的x轴坐标。y:矩形起......
  • C语言发展史
    在线书籍:54笨鸟1.C语言发展史任何一种新事物的出现都不是来自于偶然,而是时代所驱使的必然结果。1.1C语言有多伟大如果你问我:C语言有多伟大。那么,我可能会想一下,说:多伟大我不知道,但是我知道很伟大。这里,我想说一句可能有点片面的话,就是:如今这世界上,凡是带电的地方,可能......
  • Solution - Atcoder ARC171D Rolling Hash
    对于这个\(\operatorname{hash}(A_L,\cdots,A_R)\),一个比较经典的想法是做差分,即令\(s_i=\sum\limits_{j=1}^iA_jB^{i-j}\)。于是\(\operatorname{hash}(A_L,\cdots,A_R)=s_R-s_{L-1}\timesB^{R-L+1}\not=0\)。那么也就是\(s_R\not=s_{L-1}\ti......
  • 初学者如何学c语言
    你对学习如何编程感兴趣吗?如果是的话,你从C语言编程开始是不会错的。C语言是一种通用的、强大的、广泛使用的编程语言,可用于构建操作系统、开发视频游戏,甚至创造机器人。然而,对于初学者来说,学习C语言编程可能是令人生畏的。这就是为什么我们把这个初学者指南放在一起,让你开......
  • 【LeetCode:3148】矩阵中的最大得分(Java)
    题目链接3148.矩阵中的最大得分题目描述给你一个由正整数组成、大小为mxn的矩阵grid。你可以从矩阵中的任一单元格移动到另一个位于正下方或正右侧的任意单元格(不必相邻)。从值为c1的单元格移动到值为c2的单元格的得分为c2-c1。你可以从任一单元格开始......
  • 解决启动redis:应用程序无法正常启动(0xc000007b)。请单击“确定”关闭应用程序。
    解决处理方法如下目录方法一......