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

Lấy các phần tử còn lại của Tuple (Rest) trong C#

Khái niệm

Tuple 8 phần tử (Tuple<T1..T7, TRest>) lưu 7 phần tử đầu trong Item1..Item7, phần tử thứ 8 là một **Tuple lồng** truy xuất qua property Rest. Cho phép Tuple chứa **vô hạn** phần tử bằng cách lồng nhau.

Ví dụ 1: Tuple 8 phần tử (Rest là giá trị đơn)

using System;

public class Demo
{
    public static void Main(string[] args)
    {
        // Tuple.Create 8 args -> Tuple>
        var tuple1 = Tuple.Create(75, 200, 500, 700, 100, 1200, 1500, 2000);
        var tuple2 = Tuple.Create(75, 200, 500, 700, 100, 1200, 1500, 2000);

        Console.WriteLine($"Equal? {tuple1.Equals(tuple2)}"); // True
        Console.WriteLine($"HashCode1: {tuple1.GetHashCode()}");
        Console.WriteLine($"HashCode2: {tuple2.GetHashCode()}");

        Console.WriteLine($"\nItem1: {tuple1.Item1}"); // 75
        Console.WriteLine($"Item4: {tuple1.Item4}"); // 700
        Console.WriteLine($"Item7: {tuple1.Item7}"); // 1500
        Console.WriteLine($"Rest (Item8): {tuple1.Rest.Item1}"); // 2000
    }
}

Kết quả

Equal? True
HashCode1: 3247155
HashCode2: 3247155

Item1: 75
Item4: 700
Item7: 1500
Rest (Item8): 2000

Ví dụ 2: Tuple 8 phần tử với Rest là Tuple 3 phần tử (tổng 10 phần tử)

using System;

public class Demo
{
    public static void Main(string[] args)
    {
        // 7 phần tử đầu + Rest = Tuple<3 phần tử>
        var tuple1 = Tuple.Create(
            75, 200, 500, 700, 100, 1200, 1500,
            Tuple.Create("AB", 2000, "CD")
        );

        var tuple2 = Tuple.Create(
            75, 200, 500, 700, 100, 1200, 1500,
            Tuple.Create(2500, 3500, 4000, "XY") // 4 phần tử -> Tuple>
        );

        Console.WriteLine($"Equal? {tuple1.Equals(tuple2)}"); // False
        Console.WriteLine($"HashCode1: {tuple1.GetHashCode()}");
        Console.WriteLine($"HashCode2: {tuple2.GetHashCode()}");

        Console.WriteLine($"\nItem1: {tuple1.Item1}");
        Console.WriteLine($"Item4: {tuple1.Item4}");
        Console.WriteLine($"Item7: {tuple1.Item7}");

        Console.WriteLine($"\nRest của tuple1: {tuple1.Rest}"); // (AB, 2000, CD)
        Console.WriteLine($"Rest.Item1: {tuple1.Rest.Item1}"); // AB
        Console.WriteLine($"Rest.Item2: {tuple1.Rest.Item2}"); // 2000
        Console.WriteLine($"Rest.Item3: {tuple1.Rest.Item3}"); // CD

        Console.WriteLine($"\nRest của tuple2: {tuple2.Rest}"); // (2500, 3500, 4000, XY)
    }
}

Kết quả

Equal? False
HashCode1: -1121878415
HashCode2: -835095725

Item1: 75
Item4: 700
Item7: 1500

Rest của tuple1: (AB, 2000, CD)
Rest.Item1: AB
Rest.Item2: 2000
Rest.Item3: CD

Rest của tuple2: (2500, 3500, 4000, XY)

Truy xuất đệ quy các phần tử > 7


void PrintTuple(Tuple tuple, int depth = 0)
{
    // Tuple lồng có thể phức tạp, dùng reflection hoặc pattern matching (C# 7+)
}


ValueTuple (C# 7+) - Không cần Rest


// ValueTuple hỗ trợ tùy ý số phần tử, không cần lồng
var vt = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
Console.WriteLine(vt.Item8); // 8
Console.WriteLine(vt.Item10); // 10

// Deconstruction
var (a, b, c, d, e, f, g, h, i, j) = vt;

Lưu ý

  • Tuple (class) chủ yếu để tương thích ngược (.NET Framework 4.0).
  • Code mới: **dùng ValueTuple (struct)** - hiệu năng tốt, syntax đẹp, không giới hạn phần tử.
  • Rest chỉ tồn tại trên Tuple 8 phần tử (arity 8). Tuple 1-7 không có Rest.