5.9 — 8. Tuples và Deconstruction
Summary
Tuple giải quyết một nhu cầu rất thường gặp: trả về nhiều giá trị mà không phải dựng một class chỉ dùng một lần. ValueTuple của C# 7 là kiểu giá trị, có tên trường, và thay thế hẳn out cho hầu hết trường hợp. Nhưng có một chi tiết cần biết trước khi dùng rộng rãi: tên trường chỉ tồn tại ở mức trình biên dịch — chúng bị xoá khỏi IL và thay bằng Item1, Item2, nên khi đi qua reflection, serialization hay ranh giới assembly thì tên biến mất. Vì vậy tuple hợp với giá trị trả về nội bộ, không hợp với hợp đồng API công khai.
Mục tiêu bài học
Sau bài này bạn có thể:
- Dùng tuple có tên để trả nhiều giá trị thay cho
out. - Phân biệt
ValueTuplevớiTuplecũ và biết vì sao cái mới thay thế cái cũ. - Giải thích vì sao tên trường tuple biến mất trong một số ngữ cảnh.
- Viết
Deconstructcho kiểu của mình. - Quyết định khi nào dùng tuple và khi nào dùng
record.
Nội dung bài học
5.9.1 — Thay thế out
// CŨ — người gọi phải khai báo biến tr ước, không nối chuỗi được
public void GetStats(List<Order> orders, out decimal total, out int count)
{
total = orders.Sum(o => o.Total);
count = orders.Count;
}
decimal t; int c;
GetStats(orders, out t, out c);
// MỚI — có tên, đọc được, dùng được trong LINQ
public (decimal Total, int Count) GetStats(List<Order> orders)
=> (orders.Sum(o => o.Total), orders.Count);
var stats = GetStats(orders);
Console.WriteLine(stats.Total);
// Hoặc tách luôn ra hai biến
var (total, count) = GetStats(orders);
Dạng thứ hai gọi là deconstruction — tách một giá trị phức hợp thành nhiều biến.