C# ngôn ngữ định nghĩa một kiểu mở là một loại đó là hoặc là một đối số kiểu hoặc một kiểu generic định nghĩa với lập luận kiểu không rõ:
Tất cả các loại có thể được phân loại là một trong hai loại mở hoặc các loại khép kín . An kiểu mở là loại liên quan đến thông số loại. Cụ thể hơn:
- Thông số loại xác định loại mở.
- Loại mảng là loại mở nếu và chỉ khi loại phần tử của nó là loại mở.
- A loại được xây dựng là loại mở nếu và chỉ khi một hoặc nhiều đối số loại của nó là loại mở. A kiểu lồng nhau được xây dựng là một loại mở nếu và chỉ khi một hoặc nhiều đối số kiểu của nó hoặc đối số kiểu của loại chứa (s) là loại mở.
A loại đóng là loại không phải là loại mở.
Do đó T
, List<T>
, và Dictionary<string,T>
, và Dictionary<T,U>
là tất cả các loại mở (T
và U
những luận cứ loại) trong khi các loại List<int>
và Dictionary<string,int>
are closed.
Có một khái niệm liên quan: An loại chung chung không liên kết là loại chung với các đối số kiểu không xác định. Không thể sử dụng loại không liên kết trong các biểu thức khác ngoài typeof()
và bạn không thể khởi tạo hoặc gọi phương thức của nó. Ví dụ: List<>
và Dictionary<,>
là các loại không liên kết.
Để làm rõ sự khác biệt tinh tế giữa một kiểu mở và một loại không ràng buộc:
class Program {
static void Main() { Test<int>(); }
static void Test<T>() {
Console.WriteLine(typeof(List<T>)); // Print out the type name
}
}
Nếu bạn chạy đoạn này, nó sẽ in ra
System.Collections.Generic.List`1[System.Int32]
đó là tên CLR cho List<int>
. Rõ ràng khi chạy là đối số kiểu là System.Int32
. Điều này làm cho List<T>
a bị ràng buộc loại mở.
Khi chạy, bạn có thể sử dụng phản ánh để ràng buộc đối số kiểu để các tham số kiểu không xác định các kiểu generic không ràng buộc với Type.MakeGenericType
method:
Type unboundGenericList = typeof(List<>);
Type listOfInt = unboundGenericList.MakeGenericType(typeof(int));
if (listOfInt == typeof(List<int>))
Console.WriteLine("Constructed a List<int> type.");
Bạn có thể kiểm tra xem một loại là một loại generic không ràng buộc (chung kiểu định nghĩa) mà từ đó bạn có thể xây dựng các loại ràng buộc với Type.IsGenericTypeDefinition
property:
Console.WriteLine(typeof(Dictionary<,>).IsGenericTypeDefinition); // True
Console.WriteLine(typeof(Dictionary<int,int>).IsGenericTypeDefinition); // False
Để có được kiểu cởi ra từ một loại xây dựng trong thời gian chạy, bạn có thể sử dụng số Type.GetGenericTypeDefinition
method.
Type listOfInt = typeof(List<int>);
Type list = listOfInt.GetGenericTypeDefinition(); // == typeof(List<>)
Lưu ý rằng đối với loại chung, bạn có thể có định nghĩa loại hoàn toàn không bị ràng buộc hoặc định nghĩa hoàn toàn bị ràng buộc. Bạn không thể ràng buộc một số thông số loại và để người khác không bị ràng buộc. Ví dụ: bạn không thể có Dictionary<int,>
hoặc Dictionary<,string>
.
+1 thông tin tuyệt vời - Tôi đã học được điều gì đó mới mẻ hôm nay. Tôi biết rằng Danh sách <> là một loại chung chung, nhưng bây giờ tôi biết thuật ngữ kỹ thuật chính xác. – IAbstract
Bạn * có thể * thực sự đóng một phần loại chung bằng cách cung cấp một đối số kiểu tự nó là một kiểu chung mở. Tuy nhiên, đây là một kết thúc chết. Khung không chính thức nhận ra trạng thái một phần này, coi nó là không đóng và cũng không mở, và do đó nó không cho phép bạn làm bất cứ điều gì hữu ích với nó. –
giải thích tuyệt vời về sự khác biệt giữa loại mở và loại không liên kết - không biết trước! – nawfal