OK, remplaçons A
avec Fish
, IA
avec IAnimal
, B
avec Aquarium
et IB<T>
avec IContainer<T>
. Et nous allons ajouter un membre à IContainer<T>
, et une deuxième mise en œuvre de 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!
Vous pouvez mettre un tigre dans foo - foo est entré comme un récipient qui peut contenir tout animal. Mais vous pouvez seulement mettre un poisson dans un aquarium. Étant donné que les opérations que vous pouvez effectuer légalement sur un Aquarium
sont différent que les opérations que vous pouvez effectuer sur un IContainer<IAnimal>
, les types ne sont pas compatibles.
La fonction que vous voulez est appelé covariance d'interface générique et est soutenu par C# 4, mais vous devez prouver au compilateur que vous ne serez jamais mettre un tigre dans votre aquarium. Qu'est-ce que vous voulez faire est:
// 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 { }
Notez l'annotation de covariance sur IB
. Ce out
signifie que T
peut uniquement être utilisé comme sortie, et non comme une entrée. Si T
est seulement une sortie alors il n'y a aucun moyen pour quelqu'un de mettre un tigre dans ce aquarium parce qu'il n'y a pas de "mettre en" propriété ou méthode possible.
J'ai écrit un certain nombre d'articles de blog pendant que nous ajoutions cette fonctionnalité à C#; si vous êtes intéressé par les considérations de conception qui est entré dans la fonction, voir:
http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/
Quelle version de C# utilisez-vous? – Oded
[FAQ sur la covariance et la contravariance] (http://blogs.msdn.com/b/csharpfaq/archive/2010/02/16/covariance-and-contravariance-faq.aspx) et [cette série de blog] (http://blogs.msdn.com/b/ericlippert/archive/tags/covariance+and+contravariance/) par Eric Lippert – Oded
B est un IB , pas un IB. –
Servy