Comment convertir Liste en Liste lorsque ClassB hérite de ClassA?

J’ai désérialisé la chaîne json dans List et je souhaite maintenant la List en List avant de la renvoyer à partir de la méthode BindModel . J’ai besoin de casting car les méthodes s’attendent à obtenir List .

Pourquoi je reçois une erreur lors du casting? Après tout, ClassB hérite de ClassA . Que devrais-je faire?

PS cette question est étendue à partir de ce post . En ligne, new DataContractJsonSerializer(typeof(List)); au lieu de List le type sera construit au moment de l’exécution.

  public override object BindModel(...) { var serializer = new DataContractJsonSerializer(typeof(List)); MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes("[{\"id\":\"1\",\"name\":\"name\"}]")); var list = serializer.ReadObject(ms); return (List)list; } [KnownType(typeof(ClassA))] [DataContract] public class ClassA { public ClassA(); } [KnownType(typeof(ClassB))] [DataContract] public class ClassB : ClassA { [DataMember(Name = "id")] public int Id { get; set; } [DataMember(Name = "name")] public ssortingng CategoryName { get; set; } } 

Vous pouvez utiliser

  Cast() 

Par exemple:

  List listOfA = new List().Cast(); 

Ceci est en fait inférieur à Linq et est implémenté sur IEnumerable plutôt que IEnumerable mais rest utile. Ce n’est pas efficace puisque comme je l’ai dit, il essaye de le lancer.

Remember List ne permet pas la covariance qui est une nuisance. Il est préférable d’utiliser IEnumerable comme interface plutôt que List.

Tu peux dire:

  IEnumerable listOfB = new List(); IEnumerable listOfA = listOfB; // no casting required 

Vous pouvez utiliser la méthode Cast .

return list.Cast();

Regardez cette question sur Co et Contra Variance

Je jetterais les listes comme ceci:

 var listB = GetListOfB(); // returns List var listA = listB.Select(q => (A)q).ToList(); 

Cela fonctionnera pour vous?

Vous ne pouvez pas convertir une liste de sous- types en une liste de super types . Supposons que j’ai une liste de tortues et que je sois capable de la convertir en une liste d’animaux. Ensuite, je pourrais append un lion à une liste de tortues, mais un lion n’est pas du type correct.

Avec énumérables, vous pouvez le faire, cependant. Les affiches précédentes ont parfaitement raison de dire que vous pouvez convertir une liste de sous- types en un IEnumerable of SuperType . En fait, en C # 4, et IEnumerable SubType est un IEnumerable of SuperType . En effet, le paramètre générique est spécifié en tant que paramètre out.

Pour créer une List partir d’une List , une dissortingbution ne suffira pas, comme d’autres réponses l’ont noté. Vous devez construire une nouvelle liste.

Je ne suis pas particulièrement satisfait du code suggéré par d’autres réponses, alors j’offre ma propre solution. Je le ferais de cette façon:

 var baseClassList = new List(derivedClassList.Cast()); 

Certains pourraient préférer ceci:

 var baseClassList = derivedClassList.Cast().ToList(); 

Je préfère le premier parce qu’il est facile de changer le type de List à n’importe quelle autre collection avec un constructeur prenant un IEnumerable .