J'ai une configuration comme celle-ci:
abstract class Foo {}
class Bar : Foo {}
et une méthode ailleurs de cette forme:
void AddEntries(List<Foo>) {}
J'essaie d'appeler cette méthode en utilisant une liste d'objets de type Bar
List<Bar> barList = new List<Bar>()
AddEntries(barList);
mais cela me donne l'erreur:
impossible de convertir de la liste <Bar> en liste <Foo>
Y a-t-il de toute façon ce problème? J'ai besoin de conserver la définition de la méthode en utilisant la classe abstraite.
Vous pouvez rendre votre AddEntries
générique et le changer en ceci
void AddEntries<T>(List<T> test) where T : Foo
{
//your logic
}
Jetez un œil à Contraintes sur les paramètres de type pour plus d'informations.
Lisez Covariance et Contravariance dans les génériques de docs.Microsoft.com comme ceci, en particulier la section "Interfaces génériques avec des paramètres de type covariant" couvrira hors du scénario avec lequel vous travaillez.
En bref, si vous (pouvez) changer la signature de votre méthode AddEntries
en:
static void AddEntries(IEnumerable<Foo> entries)
(Notez l'utilisation de IEnumerable<Foo>
au lieu de List<Foo>
) vous pourrez faire ce que vous cherchez à faire.
La différence spécifique ici est que le IEnumerable<T>
et List<T>
sont déclarés différemment:
public interface IEnumerable<out T> : IEnumerable
public class List<T> : IList<T>, ... ...
La différence qui importe est le out
dans la déclaration de IEnumerable<T>
qui indique que c'est covariant ce qui signifie (avec la définition tirée de docs.Microsoft.com):
Covariance : vous permet d'utiliser un type plus dérivé que celui spécifié à l'origine.
Ceci n'est pas autorisé pour une simple raison. Supposons que les compilations ci-dessous:
AddEntries(new List<Bar>());
void AddEntries(List<Foo> list)
{
// list is a `List<Bar>` at run-time
list.Add(new SomethingElseDerivingFromFoo()); // what ?!
}
Si votre code compilait, vous avez un ajout dangereux (ce qui rend inutiles toutes les listes génériques) où vous avez ajouté SomethingElseDerivingFromFoo
à un List<Bar>
(type d'exécution).
Pour résoudre votre problème, vous pouvez utiliser des génériques:
void AddEntries<T>(List<T> list) where T:Foo
{
}