views:

323

answers:

4

I'm having a issue sorting an arraylist of custom objects by a string field.
This is the code I'm trying to do:

arrRegion.Sort(delegate(Portal.Entidad.Region x, Portal.Entidad.Region y)
                           {
                               return x.RegNombre.CompareTo(y.RegNombre);
                           });

But I'm getting this error:

Argument type 'anonymous method' is not assignable to parameter type 'System.Collection.IComparer'

What am I missing?

+4  A: 

This is because the Sort method expects an IComparer implementation which cannot be a delegate. For example:

public class RegionComparer : IComparer
{
    public int Compare(object x, object y)
    {
        // TODO: Error handling, etc...
        return ((Region)x).RegNombre.CompareTo(((Region)y).RegNombre);
    }
}

and then:

arrRegion.Sort(new RegionComparer());

P.S. Unless you are still stuck on .NET 1.1 don't use ArrayList. Instead use some strongly typed collections.

Darin Dimitrov
+1  A: 

You can also use System.Linq;.

arrRegion.OrderBy(x=>x.RegNombre);
Mendy
I like this way!
mslot
Thanks, but I cannot find the method .Order
lidermin
So, try OrderBy... :)
Mendy
+1  A: 

You need to actually make a class that implements IComparer, and provide that.

This can be done with a private class:

private class RegNombreComparer: IComparer
{
    int IComparer.Compare( Object xt, Object yt )  
    {
        Portal.Entidad.Region x = (Portal.Entidad.Region) xt;
        Portal.Entidad.Region y = (Portal.Entidad.Region) yt;
        return x.RegNombre.CompareTo(y.RegNombre);
    }
}

Then, you do:

arrRegion.Sort(new RegNombreComparer());

This is one downside to ArrayList, and why using List<T> (especially with LINQ) can be advantageous. It simplifies this, and lets you specify your ordering inline:

var results = arrRegion.OrderBy(i => i.RegNombre);
Reed Copsey
+4  A: 

Maybe you should used the extension methods provided in System.Linq namespace:

using System.Linq;
//...

// if you might have objects of other types, OfType<> will
// - filter elements that are not of the given type
// - return an enumeration of the elements already cast to the right type
arrRegion.OfType<Portal.Entidad.Region>().OrderBy(r => r.RegNombre);

// if there is only a single type in your ArrayList, use Cast<>
// to return an enumeration of the elements already cast to the right type
arrRegion.Cast<Portal.Entidad.Region>().OrderBy(r => r.RegNombre);

If you have control over the original ArrayList and you can change its type to a typed list like this List<Portal.Entidad.Region>, I would suggest you do it. Then you would not need to cast everything afterward and can sort like this:

var orderedRegions = arrRegion.OrderBy(r => r.RegNombre);
Marcel Gosselin
Thanks a lot! you made my day! Linq is gorgeous!!!
lidermin
Yes it is :D --
Svish
I just noticed I had used a `OfType<>()` instead of a `Cast<>()`. I updated my example with comments.
Marcel Gosselin