2009-12-06 31 views
43
  • Tại sao tôi không thể sử dụng một ràng buộc của where T : System.ValueType?
  • Tại sao Microsoft ngăn chặn loại này khỏi bị ràng buộc?

Ví dụ:Tại sao tôi không thể sử dụng System.ValueType làm ràng buộc generics?

Tại sao tôi không thể thực hiện như sau?

// Defined in a .Net class 
public void bar<T>(T a) where T : ValueType {...} 

// Defined in my class 
public void foo<T>(T a) where T : ValueType 
{ bar<T>(a); } 

Sự khác biệt trong việc sử dụng cấu trúc trên ValueType là gì?

// Defined in my class 
public void foo<T>(T a) where T : struct 
{ bar<T>(a); } 

Trả lời

60

Có hai sự khác biệt giữa việc sử dụng

where T : struct 

where T : ValueType 
  • sau này sẽ cho phép TValueType bản thân, mà là một loại tài liệu tham khảo.
  • sau này cũng sẽ cho phép T là một loại giá trị nullable

Việc đầu tiên của những khác biệt này là gần như không bao giờ những gì bạn muốn. Thứ hai có thể thỉnh thoảng hữu ích; Nullable<T> hơi kỳ quặc ở chỗ nó thỏa mãn cả ràng buộc where T : struct hoặc where T : class.

More hữu ích sẽ là hạn chế

where T : struct, System.Enum 

mà bị cấm bởi C# không có lý do chính đáng mà tôi có thể nói. Xem my blog postUnconstrained Melody project để biết thêm về điều này.

+6

Tôi phải nói, tôi đã luôn luôn tự hỏi bởi chúng tôi không thể giới hạn chúng như 'nơi T: struct, System.Enum'. Nó sẽ * rất hữu ích * vào những lúc! –

+0

Bạn _can_ thực sự làm 'trong đó T: Enum' và' trong đó T: ValueType' trong F # (sử dụng cú pháp 'khi 'T:> Enum') và thực sự, nó hoạt động như Jon mong đợi nó hoạt động. Đối với ràng buộc kiểu enum, nó hoạt động với các enums chung như 'enum ' và 'Hệ thống.Enum', và chính xác cấm các loại giá trị đồng nghĩa như 'byte' hoặc' int'. Để trả lời câu hỏi của Jon cho "tại sao", nó rất khó để thêm vào C#, hãy xem cuộc thảo luận Roslyn này: https://github.com/dotnet/roslyn/issues/262 – Abel

12

Loại giá trị không phải là lớp cơ sở của loại giá trị, nó chỉ đơn giản là vùng chứa cho giá trị khi được đóng hộp. Vì nó là một lớp container và không thuộc bất kỳ loại phân cấp nào cho các kiểu thực tế mà bạn muốn sử dụng, nó không hữu ích như một ràng buộc chung.

+0

Không hoàn toàn và không hoàn toàn. Trong IL, bạn có thể thấy rõ ràng khai báo của bất kỳ kiểu giá trị nào có 'extends System.ValueType', làm cho nó có hiệu quả là lớp cơ sở. Tôi nghĩ vai trò chính của nó là điểm đánh dấu để phân biệt giữa một lớp và một loại giá trị, nhưng tôi không chắc chắn. – Abel

6

Sử dụng struct làm ràng buộc chung là chức năng tương đương với ràng buộc "ValueType". Trong .NET, a struct is a value type.

+0

Một cấu trúc là một 'ValueType', có, nhưng không phải mọi loại giá trị là một cấu trúc, ví dụ,' ValueType' chính nó không phải là một struct, cũng không phải là các kiểu giá trị nullable. – Abel

Các vấn đề liên quan