I want to sort a string list of phrases by length, descending, so that this:
Rory Gallagher
Rod D'Ath
Gerry McAvoy
Lou Martin
would end up as:
Rory Gallagher
Gerry McAvoy
Lou Martin
Rod D'Ath
I wanted to try this first:
List<string> slPhrasesFoundInBothDocs;
. . . // populate slPhrasesFoundInBothDocs
slPhrasesFoundInBothDocs = slPhrasesFoundInBothDocs.OrderByDescending(x => x.Length);
...but the last line wouldn't compile, and intellisense suggested that I change it to:
slPhrasesFoundInBothDocs = (List<string>)slPhrasesFoundInBothDocs.OrderByDescending(x => x.Length);
...which I did. It compiles, but throws a runtime exception, namely, "Unable to cast object of type 'System.Linq.OrderedEnumerable2[System.String,System.Int32]' to type 'System.Collections.Generic.List1[System.String]'."
Do I need a fix to this code, or to attack it in a completely different way?
Use this:
slPhrasesFoundInBothDocs =
slPhrasesFoundInBothDocs
.OrderByDescending(x => x.Length)
.ToList();
The definition of the List<T> class is:
public class List<T> : IEnumerable<T>,...
List<T> class inherits from IEnumerable<T>, with OrderByDescending returning an IOrderedEnumerable<out TElement>—which also inherits from IEnumerable<T>.
The definition of the IOrderedEnumerable interface is:
public interface IOrderedEnumerable<out TElement> : IEnumerable<TElement>, IEnumerable
Check this:
IEnumerable<string> enumerable1 = new List<string>{ "x","y"};
List<string> list1 = (List<string>)enumerable1; //valid
IEnumerable<string> enumerable2 =new Collection<string>{ "x","y"};
List<string> list2 = (List<string>)enumerable2; //runtime error
It's always true that every List<T> or Collection<T> is an IEnumerable<T>. But it's not true to say that every IEnumerable<T> is a List<T>.

There wouldn't be a situation which IOrderedEnumerable<out TElement> could be cast to a List, because they are not in the same hierarchy.
So, as @cee sharper mentioned, we instead have to call the ToList() extension method, to convert IOrderedEnumerable<out TElement> to a List<T>:
List<string> list = new List{"x","xx","xxx"}.OrderByDescending(x => x.Length).ToList();
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