54 votes

Liste des débutants en C # <Interface> question

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>();
 

121voto

Adam Robinson Points 88472

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.

40voto

Dustin Campbell Points 6323

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.

4voto

Nathan Points 382

Il s’agit de la création de la liste, vous avez spécifié le T comme étant IFoo. Par conséquent, vous ne pouvez pas l’instancier sous forme de barre, car ils sont de types différents, même si Bar prend en charge IFoo.

1voto

Dan Blair Points 1580

List est le type dans ce cas et il ne s'agit pas d'une question d'héritage List <IFoo> est vraiment différent de List <Bar>. List ne connaît aucun signe de, ou hérite des caractéristiques d’IFoo ou de Bar.

J'espère que ça t'as aidé.

Prograide.com

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.

Powered by:

X