Sorting an IList in C#

Viewed 121865

So I came across an interesting problem today. We have a WCF web service that returns an IList. Not really a big deal until I wanted to sort it.

Turns out the IList interface doesn't have a sort method built in.

I ended up using the ArrayList.Adapter(list).Sort(new MyComparer()) method to solve the problem but it just seemed a bit "ghetto" to me.

I toyed with writing an extension method, also with inheriting from IList and implementing my own Sort() method as well as casting to a List but none of these seemed overly elegant.

So my question is, does anyone have an elegant solution to sorting an IList

15 Answers

You can use LINQ:

using System.Linq;

IList<Foo> list = new List<Foo>();
IEnumerable<Foo> sortedEnum = list.OrderBy(f=>f.Bar);
IList<Foo> sortedList = sortedEnum.ToList();

How about using LINQ To Objects to sort for you?

Say you have a IList<Car>, and the car had an Engine property, I believe you could sort as follows:

from c in list
orderby c.Engine
select c;

Edit: You do need to be quick to get answers in here. As I presented a slightly different syntax to the other answers, I will leave my answer - however, the other answers presented are equally valid.

You're going to have to do something like that i think (convert it into a more concrete type).

Maybe take it into a List of T rather than ArrayList, so that you get type safety and more options for how you implement the comparer.

Here's an example using the stronger typing. Not sure if it's necessarily the best way though.

static void Main(string[] args)
{
    IList list = new List<int>() { 1, 3, 2, 5, 4, 6, 9, 8, 7 };
    List<int> stronglyTypedList = new List<int>(Cast<int>(list));
    stronglyTypedList.Sort();
}

private static IEnumerable<T> Cast<T>(IEnumerable list)
{
    foreach (T item in list)
    {
        yield return item;
    }
}

The Cast function is just a reimplementation of the extension method that comes with 3.5 written as a normal static method. It is quite ugly and verbose unfortunately.

In VS2008, when I click on the service reference and select "Configure Service Reference", there is an option to choose how the client de-serializes lists returned from the service.

Notably, I can choose between System.Array, System.Collections.ArrayList and System.Collections.Generic.List

Found a good post on this and thought I'd share. Check it out HERE

Basically.

You can create the following class and IComparer Classes

public class Widget {
    public string Name = string.Empty;
    public int Size = 0;

    public Widget(string name, int size) {
    this.Name = name;
    this.Size = size;
}
}

public class WidgetNameSorter : IComparer<Widget> {
    public int Compare(Widget x, Widget y) {
        return x.Name.CompareTo(y.Name);
}
}

public class WidgetSizeSorter : IComparer<Widget> {
    public int Compare(Widget x, Widget y) {
    return x.Size.CompareTo(y.Size);
}
}

Then If you have an IList, you can sort it like this.

List<Widget> widgets = new List<Widget>();
widgets.Add(new Widget("Zeta", 6));
widgets.Add(new Widget("Beta", 3));
widgets.Add(new Widget("Alpha", 9));

widgets.Sort(new WidgetNameSorter());
widgets.Sort(new WidgetSizeSorter());

But Checkout this site for more information... Check it out HERE

using System.Linq;

var yourList = SomeDAO.GetRandomThings();
yourList.ToList().Sort( (thing, randomThing) => thing.CompareThisProperty.CompareTo( randomThing.CompareThisProperty ) );

That's pretty !ghetto.

This looks MUCH MORE SIMPLE if you ask me. This works PERFECTLY for me.

You could use Cast() to change it to IList then use OrderBy():

    var ordered = theIList.Cast<T>().OrderBy(e => e);

WHERE T is the type eg. Model.Employee or Plugin.ContactService.Shared.Contact

Then you can use a for loop and its DONE.

  ObservableCollection<Plugin.ContactService.Shared.Contact> ContactItems= new ObservableCollection<Contact>();

    foreach (var item in ordered)
    {
       ContactItems.Add(item);
    }

Convert your IList into List<T> or some other generic collection and then you can easily query/sort it using System.Linq namespace (it will supply bunch of extension methods)

Related