Brendon Davies
Brendon Davies

Reputation: 33

trying to sort a list with Linq

I've got this code that I've pieced together where I'm trying to sort a list, at least that's what I'm trying to do:

List<TagLib.File> listOfFiles = new List<TagLib.File>();
foreach (string file in files)
{
   TagLib.File fi = TagLib.File.Create(file);
   listOfFiles.Add(fi);
}

System.Linq.IOrderedEnumerable<TagLib.File> pleaseSort
    = listOfFiles.OrderBy(x => x.Tag.AlbumArtists)
                 .ThenBy(x => x.Tag.Album);

foreach (TagLib.File tl in pleaseSort)
{
    ...
}

The line that begins with

System.Linq.IOrderedEnumerable

lets the program go past it but then in the for each line stepping through the code it goes back to the IOrderedEnumerable and that is where I get the following error:

-2147024809 at least one object must implement IComparable

I'll be the first to admit that I'm no expert, this is just a pet project I'm working on, but I can't find any documentation that clearly explains what I should be looking to do in this instance. Any help will be much appreciated.

Upvotes: 0

Views: 87

Answers (1)

sstan
sstan

Reputation: 36483

By doing a little digging in the source for Tag.cs, which appears to be what you are using (it would have been nice to provide that information, it's hard to guess), I can see that AlbumArtists is defined as an array of strings (string[]). That's where the problem is coming from.

Arrays don't implement IComparable. And, if you think about it, it makes sense. If you have 2 arrays, which one should sort ahead of the other? What are the sorting rules? Do you sort on the first item of each array, on the last, or do you apply some other sorting logic? There are no clear rules for how to sort arrays, and so cannot be automatically determined by the .NET Framework, thus resulting in the error you got.

Basically, to make this work, the burden is on you to define how to sort AlbumArtists arrays from different tags. You can do that by calling the overloaded OrderBy method where you get to specify your own implementation of an IComparer.

Or, say you want the sort to be based on the first element of the AlbumArtists array, then you can change the code to only access that first element (which is comparable), and it should work fine (as long as every tag has at least one album artist in the array of course):

listOfFiles.OrderBy(x => x.Tag.AlbumArtists[0]) // access the first item only.
             .ThenBy(x => x.Tag.Album);

Upvotes: 3

Related Questions