Các lớp Tuple<T>
đã được giới thiệu trong .NET Framework 4.0. Tuple là một cấu trúc dữ liệu chứa một chuỗi các phần tử của các loại dữ liệu khác nhau.
Tuple có thể được sử dụng khi bạn muốn có một cấu trúc dữ liệu để lưu trữ dữ liệu của một đối tượng có thuộc tính, nhưng bạn không muốn tạo một kiểu dữ liệu riêng cho nó.
Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>
Ví dụ sau đây tạo ra một tuple với ba phần tử:
var person = new Tuple<int,string,string>(1, "Steve", "Jobs");
Trong ví dụ trên, chúng tôi đã tạo một Tuple
có tên là person
lưu trữ một bản ghi dữ liệu của một người. Chúng tôi đã chỉ định kiểu dữ liệu cho mỗi phần tử và chuyển các giá trị cho phương thức khởi tạo của Tuple
.
Chỉ định kiểu dữ liệu của từng phần tử trong Tuple rất cồng kềnh. Vì vậy, C# cung cấp một lớp trợ giúp Tuple
giúp trả về một thể hiện của Tuple<T>
mà không cần chỉ định kiểu dữ liệu của từng phần tử. Hãy xem ví dụ dưới đây:
var person = Tuple.Create(1, "Steve", "Jobs");
Một tuple chỉ có tối đa tám phần tử. Nó đưa ra một lỗi biên dịch khi bạn cố gắng tạo hơn tám phần tử.
var numbers = Tuple.Create(1, 2, 3, 4, 5, 6, 7, 8);
Các phần tử của Tuple có thể được truy cập bằng các thuộc tính Item<elementNumber>
. Ví dụ thuộc tính Item1, Item2, Item3, v.v. đến Item7.
Thuộc tính Item1 trả về phần tử đầu tiên, Item2 trả về phần tử thứ hai, v.v. Phần tử cuối cùng (phần tử thứ 8) sẽ được trả về bằng cách sử dụng thuộc tính Rest
.
var person = Tuple.Create(1, "Steve", "Jobs");
person.Item1; // returns 1
person.Item2; // returns "Steve"
person.Item3; // returns "Jobs"
var numbers = Tuple.Create("One", 2, 3, "Four", 5, "Six", 7, 8);
numbers.Item1; // returns "One"
numbers.Item2; // returns 2
numbers.Item3; // returns 3
numbers.Item4; // returns "Four"
numbers.Item5; // returns 5
numbers.Item6; // returns "Six"
numbers.Item7; // returns 7
numbers.Rest; // returns (8)
numbers.Rest.Item1; // returns 8
Nói chung, vị trí thứ 8 dành cho bộ dữ liệu lồng nhau mà bạn có thể truy cập bằng cách sử dụng thuộc tính Rest
.
Nếu bạn muốn nhiều hơn tám phần tử trong một tuple, bạn có thể làm điều đó bằng cách lồng một đối tượng tuple khác làm phần tử thứ tám.
Tuple con ở vị trí cuối cùng có thể được truy cập bằng cách sử dụng thuộc tính Rest
. Để truy cập phần tử của tuple con, sử dụng thuộc tính Rest.Item1.Item<elelementNumber>
.
var numbers = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12, 13));
numbers.Item1; // returns 1
numbers.Item7; // returns 7
numbers.Rest.Item1; //returns (8, 9, 10, 11, 12, 13)
numbers.Rest.Item1.Item1; //returns 8
numbers.Rest.Item1.Item2; //returns 9
Bạn có thể thêm tuple con ở bất cứ vị trí nào trong tuple cha. Tuy nhiên, nên đặt tuple con vào vị trí cuối cùng của tuple cha để có thể truy cập bằng thuộc tính Rest
.
var numbers = Tuple.Create(1, 2, Tuple.Create(3, 4, 5, 6, 7, 8), 9, 10, 11, 12, 13 );
numbers.Item1; // returns 1
numbers.Item2; // returns 2
numbers.Item3; // returns (3, 4, 5, 6, 7, 8)
numbers.Item3.Item1; // returns 3
numbers.Item4; // returns 9
numbers.Rest.Item1; //returns 13
Một phương thức có thể nhận tham số là tuple.
static void Main(string[] args)
{
var person = Tuple.Create(1, "Steve", "Jobs");
DisplayTuple(person);
}
static void DisplayTuple(Tuple<int,string,string> person)
{
Console.WriteLine($"Id = { person.Item1}");
Console.WriteLine($"First Name = { person.Item2}");
Console.WriteLine($"Last Name = { person.Item3}");
}
Một phương thức có thể trả về kiểu dữ liệu là Tuple.
static void Main(string[] args)
{
var person = GetPerson();
}
static Tuple<int, string, string> GetPerson()
{
return Tuple.Create(1, "Bill", "Gates");
}
Tuple có thể được sử dụng trong các tình huống sau:
ref
hoặc out
.C# 7.0 bổ sung lớp ValueTuple
khắc phục các hạn chế của Tuple và cũng giúp làm việc với Tuple dễ dàng hơn nữa.
C # 7.0 (.NET Framework 4.7) đã giới thiệu lớp ValueTuple, một cấu trúc đại diện cho kiểu giá trị của Tuple .
ValueTuple chỉ khả dụng trong .NET Framework 4.7. Nếu bạn không thấy ValueTuple trong dự án của mình thì bạn cần cài đặt ValueTuple. (.NET Framework 4.7 trở lên hoặc .NET Standard Library 2.0 trở lên đã bao gồm ValueTuple.)
Để cài đặt các ValueTuple, nhấp chuột phải vào Project trong solution explorer và chọn Manage NuGet Packages. Điều này sẽ mở Trình quản lý gói NuGet. Nhấp vào tab Browse, gõ ValueTuple trong hộp tìm kiếm và chọn gói System.ValueTuple, như hình bên dưới.
Thật dễ dàng để tạo và khởi tạo ValueTuple bằng dấu ngoặc đơn () và chỉ định các giá trị giữa chúng.
var person = (1, "Bill", "Gates");
//equivalent Tuple
//var person = Tuple.Create(1, "Bill", "Gates");
ValueTuple cũng có thể được khởi tạo bằng cách chỉ định kiểu dữ liệu của từng phần tử. Hãy xem ví dụ dưới đây:
ValueTuple<int,string,string> person = (1, "Bill", "Gates");
person.Item1; // returns 1
person.Item2; // returns "Bill"
person.Item3; // returns "Gates"
Sau đây là cách khai báo kiểu dữ liệu cho các phần tử.
(int, string, string) person = (1, "Bill", "Gates");
person.Item1; // returns 1
person.Item2; // returns "Bill"
person.Item3; // returns "Gates"
Xin lưu ý rằng chúng tôi đã không được sử dụng từ khóa var
trong lệnh khởi tạo tuple ở trên; thay vào đó chúng tôi cung cấp kiểu dữ liệu của từng phần tử bên trong ngoặc.
Tuple yêu cầu ít nhất hai giá trị. Hãy xem ví dụ sau:
var number = (1); // NOT a tuple, int type
var numbers = (1,2); // valid tuple
Không giống như Tuple, ValueTuple có thể nhiều hơn tám phần tử.
var numbers = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
Chúng ta có thể gán tên cho các thuộc tính ValueTuple thay vì sử dụng các tên thuộc tính mặc định Item1, Item2, v.v.
(int Id, string FirstName, string LastName) person = (1, "Bill", "Gates");
person.Id; // returns 1
person.FirstName; // returns "Bill"
person.LastName; // returns "Gates"
Chúng ta cũng có thể gán tên phần tử ở phía bên phải với các giá trị, như bên dưới.
var person = (Id:1, FirstName:"Bill", LastName: "Gates");
Xin lưu ý rằng chúng tôi có thể cung cấp tên phần tử ở bên trái hoặc bên phải nhưng không phải ở cả hai bên. Bên trái sẽ được ưu tiên hơn bên phải. Ví dụ sau đây sẽ bỏ qua tên ở phía bên phải.
// PersonId, FName, LName will be ignored.
(int Id, string FirstName, string LastName) person = (PersonId:1, FName:"Bill", LName: "Gates");
// PersonId, FirstName, LastName will be ignored. It will have the default names: Item1, Item2, Item3.
(string, string, int) person = (PersonId:1, FName:"Bill", LName: "Gates");
Chúng ta cũng có thể gán các biến làm giá trị cho phần tử.
string firstName = "Bill", lastName = "Gates";
var per = (FirstName: firstName, LastName: lastName);
Phương thức sau đây trả về ValueTuple.
static void Main(string[] args)
{
var person = GetPerson();
DisplayTuple(person);
}
static (int, string, string) GetPerson()
{
return (1, "Bill", "Gates");
}
static void DisplayTuple((int, string, string) person)
{
Console.WriteLine($"Id = { person.Item1}");
Console.WriteLine($"First Name = { person.Item2}");
Console.WriteLine($"Last Name = { person.Item3}");
}
Chúng tôi cũng có thể chỉ định các tên thành viên khác nhau cho ValueTuple được trả về từ một phương thức.
static void Main(string[] args)
{
var person = GetPerson();
}
static (int, string, string) GetPerson()
{
return (Id:1, FirstName: "Bill", LastName: "Gates");
}
Các thành viên riêng lẻ của ValueTuple có thể được truy xuất bằng cách tái cấu trúc nó. Cú pháp khai báo tái cấu trúc phân tách một ValueTuple thành các phần và gán các phần đó riêng lẻ cho các biến mới.
static void Main(string[] args)
{
// change property names
(int PersonId, string FName, string LName) person = GetPerson();
}
static (int, string, string) GetPerson()
{
return (Id:1, FirstName: "Bill", LastName: "Gates");
}
Chúng tôi cũng có thể sử dụng var thay vì tên kiểu dữ liệu rõ ràng.
static void Main(string[] args)
{
// use var as datatype
(var PersonId, var FName, var LName) person = GetPerson();
}
static (int, string, string) GetPerson()
{
return (Id:1, FirstName: "Bill", LastName: "Gates");
}
ValueTuple cũng cho phép "loại bỏ" việc tái cấu trúc cho các thành viên bạn sẽ không sử dụng.
// use discard _ for the unused member LName
(var id, var FName, _) = GetPerson();
Bạn có thể vui lòng tắt trình chặn quảng cáo ❤️ để hỗ trợ chúng tôi duy trì hoạt động của trang web.
Trong loạt bài này, tôi sẽ xem xét một số
Ngôn ngữ C# đã bật các bộ tăng áp liên
Trong bài viết này, chúng ta sẽ tìm hiểu lớp tiện ích ZipFile trong C#, cách nén tập tin và thư mục, cùng với giải nén tập tin zip.
Bài viết này sẽ giới thiệu cách đơn giản nhất mà tôi đã tìm thấy để đọc và ghi file Excel bằng C# sử dụng ExcelMapper.