2011-01-09 41 views
14

Tôi gặp vấn đề với việc hiểu cách các ràng buộc chung chung hoạt động như thế nào. Tôi nghĩ rằng tôi đang thiếu một cái gì đó quan trọng ở đây. Tôi đã kèm theo các câu hỏi của tôi trong các ý kiến ​​và sẽ biết ơn vì đã cung cấp một số giải thích.Ràng buộc chung trên T là kiểu tham chiếu và loại giá trị cùng một lúc?

//1st example: 

class C <T, U> 
    where T : class 
    where U : struct, T 
{ 
} 
//Above code compiles well, 
//On first sight it looks like U might be reference type and value type 
//at the same time. The only reason I can think of, is that T may be an 
//interface which struct can implement, Am I correct? 

//2nd example 

class CC<T, U> 
    where T : class, new() 
    where U : struct, T 
{ 
} 

//I added also a reguirement for parameterless constructor 
//and, much to my surprise, it still compiles what is 
//a bit inexplicable for me. 
//What 'U' would meet the requirement to be 
//value type, reference type and have a contructor at the same time? 

Trả lời

12

Không có gì sai với điều đó. Chúng ta hãy nhìn vào định nghĩa của constraints on the type parameters:

  • T : class - Kiểu lập luận T phải là một loại tài liệu tham khảo, bao gồm bất kỳ lớp, giao diện, đại biểu, hoặc kiểu mảng.
  • U : struct - Đối số loại U phải là loại giá trị.
  • U : T - Đối số loại U phải hoặc có nguồn gốc từ lớp T.

Vì vậy, tất cả các bạn cần làm là tìm một loại giá trị có nguồn gốc từ một loại tài liệu tham khảo. Lúc đầu mà có vẻ bất khả thi, nhưng nếu bạn nghĩ một chút khó khăn hơn bạn sẽ nhớ rằng tất cả các cấu trúc xuất phát từ lớp object, vì vậy đây hoạt động tốt cho cả hai ví dụ của bạn:

new C<object, int>(); 

Tuy nhiên nếu bạn thay đổi structclass sau đó nó sẽ không biên dịch:

// Error - Type parameter 'T' has the 'struct' constraint so 'T' 
//   cannot be used as a constraint for 'U' 
class C<T, U> 
    where T : struct 
    where U : class, T 
{ 
} 
+1

Có? và? Bạn đã chỉ định nó cho T, nó sẽ khớp với hàm tạo đối tượng. Vậy là được rồi. –

+0

Có bạn nói đúng, tôi đã đọc sai. @Mark Byers bạn nói rằng tất cả các cấu trúc xuất phát từ 'đối tượng'. SO Nếu tôi có 'lớp CS trong đó T: class {}' Mã như 'CS obj = new CS ();' sẽ không hoạt động trong khi 'DateTime' có thể chuyển thành đối tượng. – nan

+0

@Andrzej Nosal: Có, bởi vì ràng buộc 'T: class' không có nghĩa là * T có thể cast thành đối tượng *. Nó có nghĩa là * T phải là một kiểu tham chiếu *. DateTime không phải là kiểu tham chiếu. –

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