Si vous avez une interface IFoo
et une classe Bar : IFoo
, pourquoi pouvez-vous procéder comme suit:
List<IFoo> foo = new List<IFoo>();
foo.Add(new Bar());
Mais vous ne pouvez pas faire:
List<IFoo> foo = new List<Bar>();
Si vous avez une interface IFoo
et une classe Bar : IFoo
, pourquoi pouvez-vous procéder comme suit:
List<IFoo> foo = new List<IFoo>();
foo.Add(new Bar());
Mais vous ne pouvez pas faire:
List<IFoo> foo = new List<Bar>();
En un coup d'œil occasionnel, il semble que ce devrait (comme dans la bière devrait être gratuit) de travail. Cependant, une rapide vérification générale nous montre pourquoi il ne peut pas. Gardez à l'esprit que le code suivant ne compile pas. Il est destiné à montrer pourquoi il n'est pas autorisé, même s'il semble bien, jusqu'à un certain point.
public interface IFoo { }
public class Bar : IFoo { }
public class Zed : IFoo { }
//.....
List<IFoo> myList = new List<Bar>(); // makes sense so far
myList.Add(new Bar()); // OK, since Bar implements IFoo
myList.Add(new Zed()); // aaah! Now we see why.
//.....
myList
est List<IFoo>
, le sens qu'il peut prendre n'importe quelle instance d' IFoo
. Toutefois, cela entre en conflit avec le fait qu'il a été instancié en tant que List<Bar>
. Puisque le fait d'avoir un List<IFoo>
signifie que je pourrais ajouter une nouvelle instance de l' Zed
, nous ne pouvons pas permettre que, depuis la liste sous-jacente est en fait List<Bar>
, qui ne peuvent pas accueillir un Zed
.
La raison en est que le C# ne prend pas en charge la covariance et la contravariance pour les médicaments génériques en C# 3.0 et les versions antérieures. Ceci est implémenté en C# 4.0, de sorte que vous serez en mesure de faire ce qui suit:
IEnumerable<IFoo> foo = new List<Bar>();
Notez qu'en C# 4.0, vous pouvez lancer à IEnumerable<IFoo>, mais vous ne serez pas être en mesure de lancer pour la Liste<IFoo>. La raison en est que le type de sécurité, si vous avez été en mesure de lancer une Liste de<Bar> Liste<IFoo> vous serez en mesure d'ajouter d'autres IFoo des réalisateurs à la liste, de rupture de sécurité de type.
Pour plus d'arrière-plan de la covariance et la contravariance en C#, Eric Lippert a un joli blog de la série.
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.