Dans le morceau de code suivant, je m'attendais à pouvoir effectuer un casting implicite à partir de elements
à baseElements
parce que TBase
est implicitement convertible en IBase
.
public interface IBase { }
public interface IDerived : IBase { }
public class VarianceBug
{
public void Foo<TBase>() where TBase : IBase
{
IEnumerable<TBase> elements = null;
IEnumerable<IDerived> derivedElements = null;
IEnumerable<IBase> baseElements;
// works fine
baseElements = derivedElements;
// error CS0266: Cannot implicitly convert type
// 'System.Collections.Generic.IEnumerable<TBase>' to
// 'System.Collections.Generic.IEnumerable<IBase>'.
// An explicit conversion exists (are you missing a cast?)
baseElements = elements;
}
}
Cependant, je reçois l'erreur mentionnée dans le commentaire.
Citation de la spécification :
Un type
T<A1, …, An>
est convertible en variance vers un typeT<B1, …, Bn>
siT
est soit une interface, soit un type de délégué déclaré avec les paramètres du type de varianteT<X1, …, Xn>
et pour chaque paramètre de type de varianteXi
l'une des conditions suivantes est remplie :
Xi
est covariant et une référence implicite ou une conversion d'identité existe deAi
àBi
Xi
est contravariant et une référence implicite ou une conversion d'identité existe deBi
àAi
Xi
est invariant et une conversion d'identité existe deAi
àBi
En vérifiant mon code, il semble être conforme à la spécification :
-
IEnumerable<out T>
est un type d'interface -
IEnumerable<out T>
est déclaré avec des paramètres de type variante -
T
est covariant -
une conversion implicite de référence existe de
TBase
àIBase
Alors - est-ce un bug dans le compilateur C# 4 ?