C# 中 Tuple 与 ValueTuples 之间的区别

在 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 兼容,否则它通常不那么受欢迎。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

谢.锋

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值