118 votes

Impossible de convertir un IEnumerable<T> en ICollection<T>.

J'ai défini les éléments suivants :

public ICollection<Item> Items { get; set; }

Lorsque j'exécute ce code :

Items = _item.Get("001");

J'obtiens le message suivant :

Error   3   
Cannot implicitly convert type 
'System.Collections.Generic.IEnumerable<Storage.Models.Item>' to 
'System.Collections.Generic.ICollection<Storage.Models.Item>'. 
An explicit conversion exists (are you missing a cast?)

Quelqu'un peut-il m'expliquer ce que je fais de travers ? Je suis très confus quant à la différence entre Enumerable, Collections et l'utilisation de la fonction ToList()

Informations supplémentaires

Plus loin dans mon code, j'ai ce qui suit :

for (var index = 0; index < Items.Count(); index++) 

Serait-il possible de définir Items comme IEnumerable ?

144voto

Anders Abel Points 36203

ICollection<T> hérite de IEnumerable<T> afin d'assigner le résultat de

IEnumerable<T> Get(string pk)

à un ICollection<T> il y a deux façons de procéder.

// 1. You know that the referenced object implements `ICollection<T>`,
//    so you can use a cast
ICollection<T> c = (ICollection<T>)Get("pk");

// 2. The returned object can be any `IEnumerable<T>`, so you need to 
//    enumerate it and put it into something implementing `ICollection<T>`. 
//    The easiest is to use `ToList()`:
ICollection<T> c = Get("pk").ToList();

La seconde option est plus souple, mais a un impact beaucoup plus important sur les performances. Une autre option consiste à stocker le résultat sous la forme d'un IEnumerable<T> à moins que vous n'ayez besoin de la fonctionnalité supplémentaire ajoutée par le ICollection<T> l'interface.

Commentaire sur les performances supplémentaires

La boucle que vous avez

for (var index = 0; index < Items.Count(); index++)

travaille sur un IEnumerable<T> mais elle est inefficace ; chaque appel à Count() nécessite une complet énumération de tous les éléments. Vous pouvez soit utiliser une collection et l'option Count (sans les parenthèses) ou la convertir en une boucle foreach :

foreach(var item in Items)

39voto

Haris Hasan Points 17497

Vous ne pouvez pas convertir directement de IEnumerable<T> a ICollection<T> . Vous pouvez utiliser ToList méthode de IEnumerable<T> pour le convertir en ICollection<T>

someICollection = SomeIEnumerable.ToList();

1voto

Dr. ABT Points 8119

En attendant plus d'informations sur la question :

veuillez fournir plus d'informations sur le type d'article et la signature de Get

Vous pouvez essayer deux choses :

  • Pour convertir la valeur de retour de _item.Get en (ICollection)
  • deuxièmement, utiliser _item.Get("001").ToArray() ou _item.Get("001").ToList()

Veuillez noter que la deuxième option entraînera une baisse de performance pour la copie du tableau. Si la signature (type de retour) de Get n'est pas une ICollection, la première solution ne fonctionnera pas, et si elle n'est pas IEnumerable, la seconde solution ne fonctionnera pas.


Suite à votre clarification à la question et dans les commentaires, je déclarerais personnellement le type de retour de _item.Get("001") à ICollection. Cela signifie que vous n'aurez pas à faire de casting ou de conversion (via ToList / ToArray) qui impliquerait une opération de création/copie inutile.

// Leave this the same
public ICollection<Item> Items { get; set; }

// Change function signature here:
// As you mention Item uses the same underlying type, just return an ICollection<T>
public ICollection<Item> Get(string value); 

// Ideally here you want to call .Count on the collectoin, not .Count() on 
// IEnumerable, as this will result in a new Enumerator being created 
// per loop iteration
for (var index = 0; index < Items.Count(); index++) 

Je vous prie d'agréer, Madame, Monsieur, l'expression de mes salutations distinguées,

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X