5

I have the following IComparer defined for boxed RegistryItem objects:

public class BoxedRegistryItemComparer : IComparer<object>
{
    public int Compare(object left, object right)
    {
        RegistryItem leftReg = (RegistryItem)left;
        RegistryItem rightReg = (RegistryItem)right;

        return string.Compare(leftReg.Name, rightReg.Name);
    }
}

I want to use this to sort an ArrayList of boxed RegistryItems (It really should be a List<RegistryItem>, but that's out of my control).

ArrayList regItems = new ArrayList();
// fill up the list ...
BoxedRegistryItemComparer comparer = new BoxedRegistryItemComparer();
ArrayList.sort(comparer);

However, the last line gives the compiler error: "Cannot convert from BoxedRegistryItemComparer to System.Collections.IComparer". I would appreciate it if someone could point out my mistake.

Odrade
  • 7,409
  • 11
  • 42
  • 65

6 Answers6

9

BoxedRegistryItemComparer should implement System.Collections.IComparer to be used with ArrayList.Sort. you implemented System.Collections.Generic.IComparer<T> which is not the same thing.

manji
  • 47,442
  • 5
  • 96
  • 103
7

You've defined a Generic-Comparer (IComparer<T>) instead of a Comparer without a type (IComparer). ArrayList.Sort() expects a non-generic IComparer.

Generic-Types can not be casted into their non-generic equivalents.

Bobby
  • 11,419
  • 5
  • 44
  • 69
4

In case you have a situation where you don't have any control over the Comparer or the Sorter, here are two mini-classes which can convert between the two types (untested):

private class GenericComparer<T> : IComparer<T>
{
    IComparer _Comparer;
    public GenericComparer(IComparer comparer)
    {
        _Comparer = comparer;
    }
    public int Compare(T a, T b)
    {
        return _Comparer.Compare(a, b);
    }
}

private class NonGenericComparer<T> : IComparer
{
    IComparer<T> _Comparer;
    public NonGenericComparer(IComparer<T> comparer)
    {
        _Comparer = comparer;
    }
    public int Compare(object a, object b)
    {
        return _Comparer.Compare((T)a, (T)b);
    }
}
Benjol
  • 63,995
  • 54
  • 186
  • 268
1

Perhaps it is a crutch, but it works:

            arrayList.Sort(Comparer<object>.Create(
            (x, y) => ((RegistryItem)x).Name.CompareTo(((RegistryItem)y).Name)));
0
public class BoxedRegistryItemComparer : IComparer {
...
}
Jason Plank
  • 2,336
  • 5
  • 31
  • 40
MaLio
  • 2,498
  • 16
  • 23
0

An alternative to above post would be to have your comparer class implement both interfaces, then you can cast IComparer<T> to IComparer should you need both.

public class MyComparer<T> : IComparer<T>, IComparer
mhapps
  • 93
  • 8