2011-07-08 31 views
14

Với các lớp học sau ...Tại sao không thể suy ra các kiểu chung chung lồng nhau?

public abstract class FooBase<TBar> where TBar : BarBase{} 
public abstract class BarBase{} 
public class Bar1 : BarBase{} 
public class Foo1 : FooBase<Bar1> {} 

... và các phương pháp sau đây ...

public TBar DoSomething<TFoo, TBar>(TFoo theFoo) 
    where TFoo : FooBase<TBar> 
    where TBar : BarBase 
{ 
    return default(TBar); 
} 

Tại sao các dòng mã sau đây không thể bao hàm các kiểu trả về?

Bar1 myBar = DoSomething(new Foo1()); 

Thay vào đó tôi phải xác định các loại chung như thế này ...

Bar1 myBar = DoSomething<Foo1, Bar1>(new Foo1()); 

Trả lời

21

loại Phương pháp suy luận bỏ qua những hạn chế chung trên các thông số loại phương pháp (*). Lý do loại suy luận phương pháp chỉ về các khoản khấu trừ có thể được thực hiện bằng cách so sánh đối số đến loại thông số chính thức. Vì tham số kiểu chung duy nhất xuất hiện trong các kiểu tham số chính thức của bạn là TFoo, nên không có cách nào để suy ra TBar.

Nhiều người cho rằng quyết định thiết kế này là sai, sai, sai. Mặc dù tôi có quan điểm của họ, quyết định này không dẫn đến những gì trong quan điểm của tôi một số tài sản tốt đẹp. Đối với một cuộc tranh luận kéo dài về vấn đề này, xem bazillion hoặc lâu hơn ý kiến ​​về bài viết trên blog này nói với tôi rằng tôi sai, sai, sai:

http://blogs.msdn.com/b/ericlippert/archive/2009/12/10/constraints-are-not-part-of-the-signature.aspx


(*) Lưu ý rằng tôi đã nói những hạn chế về thông số loại phương thức bị bỏ qua, không phải là các ràng buộc nói chung. Nếu các kiểu tham số chính quy suy luận được xây dựng theo kiểu chung như vậy thì việc xây dựng vi phạm ràng buộc tham số kiểu của chúng thì thực tế này gây ra suy luận kiểu không thành công và phương pháp không phải là một ứng cử viên cho độ phân giải quá tải. Nhưng trong mọi trường hợp, chúng tôi khấu trừ từ một ràng buộc khác với "Hmm, rõ ràng điều này sẽ không hoạt động".

+0

Tôi nghĩ một số người sẽ tự hỏi tại sao chúng tôi sẽ không ** thử ** sử dụng ràng buộc để suy ra loại. Một cách khác để suy nghĩ về điều này, là nếu bạn xem xét đầu tiên chúng ta phải xác định những loại bê tông nào đang được sử dụng cho TFoo và TBar, thì bất kỳ mã nào tham chiếu đến các kiểu này hiện nay đều sử dụng loại cụ thể. Trong trường hợp của 'FooBase ', ở đây chúng tôi đang nói ** sau ** bạn biết loại 'TBar' là gì, sau đó' FooBase 'sẽ trở thành 'FeeBase '. Ràng buộc này không thể được sử dụng như là một phần của suy luận kiểu, bởi vì chúng ta không biết kiểu cho đến khi suy luận hoàn thành. Nó sẽ là logic tròn. – AaronLS

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