Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> C#

Tuple trong C# 4.0+ - Cú pháp và sử dụng

Tuple là cấu trúc dữ liệu lightweight nhóm nhiều giá trị khác kiểu vào một đối tượng duy nhất. Từ C# 7.0 có ValueTuple (struct) với cú pháp SugarSyntax tốt hơn Tuple class (reference type) cũ.

1. Tuple Class (C# 4.0 - Legacy)

// Cú pháp cũ - Reference type, heap allocation
Tuple<int, string> person = new Tuple<int, string>(32, "Steve");
Console.WriteLine(person.Item1); // 32
Console.WriteLine(person.Item2); // Steve

// Tối đa 8 phần tử (Tuple<T1..T7, TRest>)
var tuple8 = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9));

2. ValueTuple (C# 7.0+ - Khuyên dùng)

Struct, stack-allocated, có tên thành phần, deconstruction, so sánh giá trị.

Cú pháp tạo

// Cú pháp tường minh
(int Age, string Name) person = (32, "Steve");

// Type inference (var)
var person2 = (Age: 25, Name: "Alice", Active: true);

// Tuple literal
var point = (X: 10, Y: 20);

Truy cập thành phần

Console.WriteLine(person.Age);    // 32 (tên)
Console.WriteLine(person.Item1);  // 32 (tên tự động Item1, Item2...)

Console.WriteLine(person2.Name);  // Alice
Console.WriteLine(person2.Item3); // True

Deconstruction (Phân rã)

var (age, name) = person; // age=32, name="Steve"
var (_, nameOnly) = person; // Bỏ qua age với discard _

// Deconstruction trong foreach
var points = new[] { (1, 2), (3, 4), (5, 6) };
foreach (var (x, y) in points)
    Console.WriteLine($"({x}, {y})");

So sánh và Equality

var t1 = (1, "a");
var t2 = (1, "a");
var t3 = (2, "b");

Console.WriteLine(t1 == t2); // True (structural equality)
Console.WriteLine(t1.Equals(t2)); // True
Console.WriteLine(t1.GetHashCode() == t2.GetHashCode()); // True

Ví dụ thực tế: Return multiple values từ method

using System;

class Program
{
    // Trả về tuple có tên
    static (int Sum, int Count, double Average) GetStats(int[] numbers)
    {
        if (numbers.Length == 0) return (0, 0, 0.0);
        int sum = 0;
        foreach (var n in numbers) sum += n;
        return (sum, numbers.Length, (double)sum / numbers.Length);
    }
    
    static void Main()
    {
        var stats = GetStats(new[] { 10, 20, 30, 40, 50 });
        Console.WriteLine($"Sum: {stats.Sum}, Count: {stats.Count}, Avg: {stats.Average}");
        
        // Deconstruction
        var (sum, count, avg) = GetStats(new[] { 1, 2, 3 });
        Console.WriteLine($"{sum}, {count}, {avg}");
    }
}

Kết quả

Sum: 150, Count: 5, Avg: 30
6, 3, 2

So sánh Tuple Class vs ValueTuple

Đặc điểmTuple<...> (Class)ValueTuple (Struct)
KiểuReference typeValue type (struct)
AllocationHeapStack (thường)
Tên thành phầnKhông (Item1, Item2...)Có (tên tùy chỉnh)
DeconstructionKhôngCó
EqualityReferenceStructural (giá trị)
MutableImmutableMutable (có thể gán lại)
PerformanceChậm hơn (GC)Nhanh hơn

Khuyến nghị: Luôn dùng ValueTuple (C# 7+) cho code mới. Chỉ gặp Tuple class trong legacy code.