public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Comment puis - je jeter List<Client>
à List<IDic>
?
public interface IDic
{
int Id { get; set; }
string Name { get; set; }
}
public class Client : IDic
{
}
Comment puis - je jeter List<Client>
à List<IDic>
?
Réponses:
Vous ne pouvez pas le lancer (en préservant l'identité de référence) - ce serait dangereux. Par exemple:
public interface IFruit {}
public class Apple : IFruit {}
public class Banana : IFruit {}
...
List<Apple> apples = new List<Apple>();
List<IFruit> fruit = apples; // Fortunately not allowed
fruit.Add(new Banana());
// Eek - it's a banana!
Apple apple = apples[0];
Vous pouvez maintenant convertir un List<Apple>
en un IEnumerable<IFruit>
dans .NET 4 / C # 4 en raison de la covariance, mais si vous voulez un, List<IFruit>
vous devez créer une nouvelle liste. Par exemple:
// In .NET 4, using the covariance of IEnumerable<T>
List<IFruit> fruit = apples.ToList<IFruit>();
// In .NET 3.5
List<IFruit> fruit = apples.Cast<IFruit>().ToList();
Mais ce n'est pas la même chose que de lancer la liste d'origine - car il existe maintenant deux listes distinctes . C'est sûr, mais vous devez comprendre que les modifications apportées à une liste ne seront pas vues dans l'autre liste. (Les modifications apportées aux objets auxquels les listes se réfèrent seront bien sûr visibles.)
List<IFruit>
qui était en fait une référence à un fichier List<Apple>
. À quoi vous attendriez-vous si vous ajoutiez une Banana
référence à cela List<IFruit>
?
using
directive pour System.Linq
, ou pourquoi vous essayez de l'appeler, je ne sais pas comment vous vous attendez à ce que je puisse vous aider. Je vous suggère de faire plus de recherches, et si vous êtes toujours bloqué, vous posez une question avec un exemple reproductible minimal .
Un itérateur Cast et .ToList ():
List<IDic> casted = input.Cast<IDic>().ToList()
fera l'affaire.
À l'origine, j'ai dit que la covariance fonctionnerait - mais comme Jon l'a souligné à juste titre; non ce ne sera pas!
Et à l'origine, j'ai aussi bêtement arrêté l' ToList()
appel
Cast
renvoie une IEnumerable<T>
, pas une List<T>
- et non, la covariance ne permettra pas cette conversion, car elle serait dangereuse - voir ma réponse.
ToList()
manquait avant de lire votre commentaire; mais oui, comme vous l'avez montré bien sûr, la Covariance ne fonctionnera pas! Doh!
Cast
appel dans .NET 4, tant que vous spécifiez l'argument de type à ToList
.
J'ai aussi eu ce problème et après avoir lu la réponse de Jon Skeet, j'ai modifié mon code de l'utilisation List<T>
à l'utilisation IEnumerable<T>
. Bien que cela ne répond pas à la question de l' origine de l'OP Comment puis - je jeter List<Client>
àList<IDic>
, il n'évite la nécessité de le faire et peut donc être utile pour les autres qui rencontrent ce problème. Cela suppose bien sûr que le code qui nécessite l'utilisation de List<IDic>
est sous votre contrôle.
Par exemple:
public void ProcessIDic(IEnumerable<IDic> sequence)
{
// Implementation
}
Au lieu de:
public void ProcessIDic(List<IDic> list)
{
// Implementation
}
List<Client> listOfA = new List<Client>();
List<IDic> list = listOfA.Cast<IDic>().ToList();
Ce n'est possible qu'en créant de nouveaux List<IDic>
et en transférant tous les éléments.
Dans .Net 3.5, vous pouvez effectuer les opérations suivantes:
List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>());
Le constructeur de List dans ce cas prend un IEnumerable.
list n'est cependant convertible qu'en IEnumerable. Même si myObj peut être convertible en ISomeInterface, le type IEnumerable n'est pas convertible en IEnumerable.