Et OrderBy Liste vs IOrderedEnumerable
J'ai couru à travers un problème inattendu avec le code suivant.
List<string> items = new List<string>();
items = items.OrderBy(item => item);
Ce code génère l'erreur:
Impossible de convertir implicitement le type de Système.Linq.IOrderedEnumerable' à 'Système.Les Collections.Génériques.Liste". Une conversion explicite existe (vous manque un plâtre?)
Il semble que je peux changer items
pour être de type IEnumerable<string>
et l'erreur disparaît. Mais j'ai besoin d'être en mesure d'ajouter des éléments à la liste, qui IEnumerable
ne prend pas en charge.
Quelqu'un peut-il m'aider à comprendre cette erreur, et que la meilleure solution est? Est-il sécuritaire de tout simplement jeté le résultat?
- Vous êtes le premier de la création d'une liste vide, et ensuite de tenter de sorte que la liste vide?
- Bien sûr que non. Ce que je fais ici est d'essayer de créer un extrait de simple qui illustre le problème avec aussi peu de code que possible.
- Mais il ne le démontre pas la question, parce que vous avez supprimé, si bien qu'il n'est pas clair de savoir si vous avez déjà une liste que vous avez besoin de trier, ou si vous avez une énumération que vous êtes en train de trier et d'entrer dans une liste.
Vous devez vous connecter pour publier un commentaire.
Pourquoi ne pas trier la liste en place à l'aide de la
Sort()
méthode d'instance; puis vous pouvez ajouter des éléments à plus tard si vous le souhaitez:Ou, utiliser une collection ordonnée comme un arbre de recherche binaire.
SortedSet<T>
peut adapter le projet de loi, en fonction de vos besoins.La solution proposée par les autres:
... crée une autre liste avec les éléments d'origine dans un nouvel ordre. C'est utile seulement si vous devez conserver l'original de la commande pour un autre but; c'est plutôt plus gourmands en mémoire de tri de la liste en place.
Aussi loin que la compréhension de l'erreur, c'est simple:
List<T>
n'est pas un sous-type deIOrderedEnumerable<T>
, donc il n'y a pas de référence implicite de conversion entre les deux. Le cast explicite que le compilateur suggère de satisfaire le compilateur, mais ce sera un échec au moment de l'exécution en raison de l'objet renvoyé parOrderBy<T>
n'hérite pas deList<T>
.MODIFIER
Un exemple de
List<T>.Sort(Comparison<T>)
, en supposant que le typeMyType
a unKey
propriété d'un certain type de type T, oùT : IComparable<T>
:Sort()
mais il n'est pas tout à fait aussi pratique car mes données réelles est une classe et je veux plus compliqué les règles de tri. Mais je suppose que je peux toujours créer un personnalisé comparer.IComparable<T>
sur la classe, etList.Sort<T>()
utilisera que la mise en œuvre.Comparison<T>
ou lambda(a,b)=>return int
comme une fonction de tri (que ce soit en ligne ou en passant un nom de méthode), ce qui est parfois plus pratique. (Voir: msdn.microsoft.com/en-us/library/tfakywbh.aspx)Sort
surcharge qui prend unComparison<T>
délégué, de sorte que vous pouvez toujours utiliser une expression lambda.Vous avez besoin de convertir le
IEnumerable
à unList
. Essayez ceci:ToList()
est? Par exemple, est-il besoin d'allouer une nouvelle collection, puis copier chaque élément de la liste.Sort()
option à la place.Essayer cette
Vous avez besoin d'utiliser LINQ ToList() la méthode
Vous ne pouvez pas lancer directement à partir de IEnumerable<> Liste<>
De tri d'une liste de chaînes, vous n'avez pas besoin de Linq, en premier lieu, utilisez simplement
Sort()
:OrderBy() est une méthode d'extension de IEnumerable - et pas Liste.
Lorsque le compilateur rencontre le OrderBy() la méthode d'extension, il jette de la variable de portée pour un IOrderedEnumerable où il peut effectuer un tri par CreateOrderedEnumerable méthode à l'aide de IComparer et coll. Une fois triés, le compilateur crache de la variable comme IEnumerable - habituellement.
Suggestion: utilisez le mot-clé var de type "articles" dans le LinQ clause.
Certainement les options proposées ci-dessus à l'aide de la Sort() et ToList() méthodes de travail - cependant, leur utilisation implique gourmand opérateurs et vous perdez l'avantage de chargement paresseux.
Voici une bonne ventilation ici:
C# de Tri et de comparaison OrderBy entre l'exécution de Tri() et OrderBy().