Có một số lớp nhất định trong Khung có hiệu quả truyền các đặc tính đặc biệt cho tất cả các kiểu bắt nguồn từ chúng nhưng bản thân không sở hữu các đặc điểm đó . Bản thân CLR không cấm sử dụng các lớp đó làm ràng buộc, nhưng các kiểu chung bị ràng buộc với chúng sẽ không có được các đặc tính không kế thừa như cách các kiểu cụ thể sẽ làm. Những người tạo ra C # đã quyết định rằng vì hành vi như vậy có thể khiến một số người bối rối và họ không thấy bất kỳ tính hữu ích nào của nó, họ nên cấm những ràng buộc như vậy thay vì cho phép họ hành xử như họ làm trong CLR.
Nếu, ví dụ, một được phép viết: void CopyArray<T>(T dest, T source, int start, int count)
; người ta có thể truyền dest
và source
đến các phương thức mong đợi một đối số kiểu System.Array
; hơn nữa, người ta sẽ nhận được xác thực thời gian biên dịch dest
và source
là các kiểu mảng tương thích, nhưng người ta sẽ không thể truy cập các phần tử của mảng bằng []
toán tử.
Việc không thể sử dụng Array
như một ràng buộc chủ yếu là khá dễ dàng để khắc phục, vì void CopyArray<T>(T[] dest, T[] source, int start, int count)
sẽ hoạt động trong hầu hết các tình huống mà phương pháp cũ sẽ hoạt động. Tuy nhiên, nó có một điểm yếu: phương thức trước đây sẽ hoạt động trong trường hợp một hoặc cả hai đối số là kiểu System.Array
trong khi từ chối các trường hợp mà các đối số là kiểu mảng không tương thích; thêm một quá tải trong đó cả hai đối số đều thuộc loại System.Array
sẽ làm cho mã chấp nhận các trường hợp bổ sung mà nó phải chấp nhận, nhưng cũng làm cho nó chấp nhận sai các trường hợp không nên.
Tôi thấy quyết định đặt ra ngoài vòng pháp luật hầu hết các ràng buộc đặc biệt là khó chịu. Ý nghĩa duy nhất không có ý nghĩa ngữ nghĩa sẽ là System.Object
[vì nếu điều đó là hợp pháp như một ràng buộc, thì bất cứ điều gì sẽ thỏa mãn nó]. System.ValueType
có lẽ sẽ không hữu ích lắm, vì kiểu tham chiếu ValueType
không thực sự có nhiều điểm chung với kiểu giá trị, nhưng hợp lý thì nó có thể có một số giá trị trong các trường hợp liên quan đến Phản chiếu. Cả hai System.Enum
và System.Delegate
sẽ có một số công dụng thực sự, nhưng vì những người tạo ra C # không nghĩ về chúng nên chúng nằm ngoài vòng pháp luật mà không có lý do chính đáng.