2012-01-17 2 views
8

Hãy xem xét các lớp sau đây:Class và mức Phương pháp chung loại hạn chế tương tác

public class DerivedClassPool<TBase> where TBase : class 
{ 
    public TBase Get(Type componentType) 
    { 
     // Not important, but you get the idea 
     return Activator.CreateInstance(componentType) as TBase; 
    } 

    public TDerived SomeMethod<TDerived>() where TDerived : TBase 
    { 
     return Get(typeof(TBase)) as TDerived; 
    } 
} 

Lưu ý rằng tôi đã hạn chế đối số lớp generic TBase là một lớp: where TBase : class
Tôi cũng hạn chế TDerived chung đối số phương thức là TBase hoặc một cái gì đó bắt nguồn từ đó: where TDerived : TBase.

tôi nhận được một lỗi trên as TDerived dòng:

Tham số loại 'TDerived' không thể được sử dụng với 'là' điều hành bởi vì nó không có một hạn chế loại lớp hay một 'lớp' chế

tôi hiểu rằng để ngăn chặn các lỗi tôi cần phải thêm các hạn chế class, vì vậy tôi muốn nhận được:

where TDerived : class, TBase 

Tại sao tôi phải làm điều này khi TBase đã bị ràng buộc là một lớp và TDerived bị ràng buộc là TBase hoặc bắt nguồn từ nó?

+1

Xem http://stackoverflow.com/questions/8002148/c-sharp-generics-contraints-propagation. Eric đưa nó ra khỏi đó. –

+1

@ Jason, tôi nghĩ rằng nó đọc tốt hơn với 'nhưng'. – Joey

+1

@Joey: Đủ công bằng. Tôi chỉ ghét khi câu bắt đầu bằng 'nhưng', mặc dù việc sử dụng các từ ghép để bắt đầu câu được coi là chính xác trong những ngày này. Tôi đổ lỗi cho giáo viên tiếng Anh trung học của tôi. Ông là một người gắn bó cho các công ước tiếng Anh cổ điển. –

Trả lời

8

CẬP NHẬT: Câu hỏi này là the subject of my blog on September 19th, 2011. Cảm ơn vì câu hỏi tuyệt vời của bạn!


Tại sao tôi phải làm điều này khi TBase đã hạn chế được một lớp học và TDerived bị hạn chế là một TBase hoặc có nguồn gốc từ nó?

Vì loại giá trị có thể được bắt nguồn từ loại tham chiếu. int được lấy từ các loại tham chiếu objectSystem.ValueType và triển khai một số giao diện. Điều đó không làm cho int loại tham chiếu.

Hoàn toàn hợp pháp để bạn gọi SomeMethod<int> trên một phiên bản DerivedClassPool<object> vì int được lấy từ đối tượng.

Hiện tại, có trường hợp phê bình của bạn sẽ được đảm bảo. Người ta có thể xây dựng các tình huống trong đó hai tham số kiểu có liên quan theo cách mà cả hai chỉ có thể là kiểu tham chiếu, nhưng chỉ một trong số chúng được phân loại theo ngôn ngữ là "được biết đến là kiểu tham chiếu".

Là một bài tập cho người đọc: bạn có thể tìm thấy nó không? Nó có thể là cần thiết để đọc kỹ phần 10.1.5 của đặc điểm kỹ thuật cho một định nghĩa chính xác của "được biết đến là một loại tài liệu tham khảo".

+0

Có thể tạo các loại giá trị riêng của chúng tôi có nguồn gốc từ các loại tham chiếu (trong C#) không? –

+0

@GeorgeDuckett Tại sao điều đó có liên quan? –

+0

@OskarKjellin: Không phải, tôi chỉ tò mò thôi. :) –

2

TBase có thể là một giao diện và do đó TDerived có thể là một loại giá trị.

+0

TBase cần phải là một lớp học? –

+1

bạn chắc chắn về điều đó? http://msdn.microsoft.com/en-us/library/d5x73970.aspx: 'Đối số kiểu phải là một kiểu tham chiếu; điều này cũng áp dụng cho bất kỳ loại, giao diện, đại biểu hoặc loại mảng nào.' –

+1

Không biết về điều đó. Tricky rằng 'class' có nghĩa là" loại giá trị "trong trường hợp này là –