OK, chúng ta hãy thay thế A
với Fish
, IA
với IAnimal
, B
với Aquarium
, và IB<T>
với IContainer<T>
. Và chúng ta sẽ thêm một thành viên IContainer<T>
và thực hiện thứ hai của IAnimal
:
// Model
public class Fish : IAnimal { }
public class Tiger : IAnimal { }
// ModelLogic
public class Aquarium : IContainer<Fish>
{
public Fish Contents { get; set; }
}
// Model Interface
public interface IAnimal { }
// ModelLogic Interface
public interface IContainer<T> where T : IAnimal
{
T Contents { get; set; }
}
IContainer<IAnimal> foo = new Aquarium(); // Why is this illegal?
foo.Contents = new Tiger(); // Because this is legal!
Bạn có thể đặt một Tiger vào foo - foo được gõ như một container có thể chứa bất kỳ động vật. Nhưng bạn chỉ có thể đặt một con cá vào một bể cá. Vì các hoạt động bạn có thể thực hiện hợp pháp trên Aquarium
là khác nhau so với các thao tác bạn có thể thực hiện trên IContainer<IAnimal>
, các loại này không tương thích.
Các tính năng mà bạn muốn được gọi là chung giao diện hiệp phương sai và nó là hỗ trợ bởi C# 4, nhưng bạn phải chứng minh cho trình biên dịch mà bạn sẽ không bao giờ đặt một con hổ vào bể cá của bạn. Những gì bạn muốn làm là:
// Model
public class A : IA { }
// ModelLogic
public class B : IB<A> { }
// Model Interface
public interface IA { }
// ModelLogic Interface
public interface IB<out T> where T : IA { }
Chú ý chú thích hiệp phương sai trên IB
. Điều này out
có nghĩa là T
chỉ có thể được sử dụng làm đầu ra, không phải là đầu vào. Nếu T
chỉ là một đầu ra thì không có cách nào để một người nào đó để đặt một con hổ vào bể cá đó bởi vì không có "đưa vào" tài sản hoặc phương pháp có thể.
Tôi đã viết một số bài viết trên blog trong khi chúng tôi đã thêm tính năng đó vào C#; nếu bạn quan tâm đến những cân nhắc thiết kế mà đi vào tính năng này, xem:
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/
Nguồn
2012-04-27 14:41:16
Bạn đang sử dụng phiên bản C# nào? – Oded
[Câu hỏi thường gặp về hiệp phương sai và câu hỏi thường gặp] (http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx) và [loạt blog này] (http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/) bởi Eric Lippert – Oded
B là IB , không phải là IB. –
Servy