I ran across an unexpected problem with the following code.
List<string> items = new List<string>();
items = items.OrderBy(item => item);
This code generates the error:
Cannot implicitly convert type 'System.Linq.IOrderedEnumerable' to 'System.Collections.Generic.List'. An explicit conversion exists (are you missing a cast?)
It appears I can change items
to be of type IEnumerable<string>
and the error goes away. But I need to be able to add items to the list, which IEnumerable
doesn't support.
Can someone help me understand this error, and what the easiest fix is? Is it safe to simply cast the result?
According to MSDN, OrderBy is stable, as is OrderByDescending .
In LINQ, the OrderBy operator is used to sort the list/ collection values in ascending order. In LINQ, if we use order by the operator by default, it will sort the list of values in ascending order. We don't need to add any ascending condition in the query statement.
In a query expression, the orderby clause causes the returned sequence or subsequence (group) to be sorted in either ascending or descending order. Multiple keys can be specified in order to perform one or more secondary sort operations. The sorting is performed by the default comparer for the type of the element.
Why not just sort the list in place using the Sort()
instance method; then you can add items to it later if you like:
List<string> items = GetSomeItems();
items.Sort();
Or, use an ordered collection like a binary search tree. SortedSet<T>
might fit the bill, depending on your needs.
The solution suggested by the others:
items = items.OrderBy(item => item).ToList();
... creates another list with the original items in a new order. This is only useful if you need to preserve the original ordering for some other purpose; it's rather more wasteful of memory than sorting the list in place.
As far as understanding the error, it's simple: List<T>
isn't a subtype of IOrderedEnumerable<T>
, so there's no implicit reference conversion between the two. The explicit cast that the compiler suggests will satisfy the compiler, but it will fail at run time because the object returned by OrderBy<T>
does not inherit from List<T>
.
EDIT
An example of List<T>.Sort(Comparison<T>)
, assuming the type MyType
has a Key
property of some type type T where T : IComparable<T>
:
List<MyType> items = GetSomeItems();
items.Sort((a, b) => a.Key.CompareTo(b.Key));
You need to convert the IEnumerable
to a List
. Try this:
items = items.OrderBy(item => item).ToList();
You need to use LINQ's ToList() method
items = items.OrderBy(item => item).ToList();
You can't cast directly from IEnumerable<> to List<>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With