7
votes

c # linq `list méthode .Addrange 'ne fonctionne pas

J'ai une interface définie comme ci-dessous: xxx pré>

et deux classes LINQ-TO-SQL implémentant cette interface: p> xxx pré>

i Avoir des listes iEnumérables A et B remplies par les enregistrements de base de données de Tblattesta et TblTestB P> xxx pré>

Toutefois, ce qui suit n'est pas autorisé: p>

foreach(tblTestA item in a)
    list.Add(item)

foreach(tblTestB item in b)
    list.Add(item)


0 commentaires

4 Réponses :


6
votes

Vous ne faites rien de mal: Liste .Addrange attend un iEnumerable . Il n'acceptera pas un iEnumerable ou iEnumerable .

Votre foreach BOOPS. Sinon, vous pouvez utiliser couler pour modifier les types: xxx


0 commentaires

0
votes

A et B est de type iEnumerable et ienumerable
Tandis que list.addrange nécessite le paramètre de type ienumerable


2 commentaires

Eh bien, ils ont besoin que l'argument soit convertible à ienumerable . Que ce soit le cas ou non dépend de la version de C # que vous utilisez ...


Je suppose que vous avez raison - je ne connais pas le C # 4, merci :)



9
votes

Cela fonctionne dans C # 4, en raison de Covariance générique . Contrairement aux versions précédentes de C #, il existe une conversion de ienumerable à ienumerable . .

La fonctionnalité est dans le CLR de V2, mais elle n'a été exposée que dans le C # 4 (et les types de cadre ne l'ont pas profité avant .net 4 soit). Il seul s'applique aux interfaces génériques et aux délégués (non classes) et uniquement pour les types de référence (il n'y a donc pas de conversion de ienumerable sur ienumerable < / code> Par exemple.) Cela ne fonctionne aussi que lorsque cela a du sens - iEnumerable est covariant comme des objets uniquement "Out" de l'API, tandis que iliste est invariant parce que vous pouvez ajouter des valeurs avec cette API aussi.

Contraviarariance générique est également pris en charge, travaillant dans l'autre sens - vous pouvez donc convertir de icomparer à icomparer . .

Si vous n'utilisez pas C # 4, la suggestion de TIM d'utiliser énumérable.Cast est une bonne - vous perdez une petite efficacité, mais cela fonctionnera.

Si vous voulez en savoir plus sur la variance générique, Eric Lippert a un Longues séries de blog postes à ce sujet , et j'ai donné une discussion à ce sujet à NDC 2010 que vous pouvez regarder sur le page vidéo NDC .


0 commentaires

1
votes

L'Addrange s'attend à une liste d'objets d'interface, et vos varaibles "A" et "B" sont définies comme une liste d'objets de classe dérivés. De toute évidence, il semble raisonnable que .NET puisse logiquement que le saut et les traiter comme des listes d'objets d'interface car ils mettent en œuvre l'interface, cette logique n'était tout simplement pas intégrée à. Net allant jusqu'à 3.5.

Cependant, cette capacité (appelée "covariance") a été ajoutée à .NET 4.0, mais jusqu'à ce que vous mettriez la mise à niveau avec une boucle, ou peut-être essayez d'appeler TOARRAY (), puis de lancer le résultat à un TaskInterface [], ou peut-être une requête LINQ pour casse à chaque élément et créer une nouvelle liste, etc.


0 commentaires