“No se puede convertir a IComparer”
Pregunta
He definido la siguiente IComparer para objetos RegistryItem enmarcadas:
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);
}
}
Quiero usar esto para ordenar un ArrayList de RegistryItems en caja (En realidad debería ser un List<RegistryItem
>, pero que está fuera de mi control).
ArrayList regItems = new ArrayList();
// fill up the list ...
BoxedRegistryItemComparer comparer = new BoxedRegistryItemComparer();
ArrayList.sort(comparer);
Sin embargo, la última línea da el error del compilador: "No se puede convertir de BoxedRegistryItemComparer a System.Collections.IComparer". Le agradecería que si alguien podría señalar mi error.
Solución
BoxedRegistryItemComparer
debe aplicar System.Collections.IComparer
para ser utilizado con ArrayList.Sort
. Ha implementado System.Collections.Generic.IComparer<T>
que no es lo mismo.
Otros consejos
Se ha definido un Generic-Comparer (IComparer<T>
) en lugar de un Comparer sin un tipo (IComparer
) . ArrayList.Sort()
espera un no genérico IComparer
.
Generic-Tipos no pueden ser fundidas en sus equivalentes no genéricos.
En caso de tener una situación en la que usted no tiene ningún control sobre el comparador o el Clasificador, aquí hay dos mini-clases que puede convertir entre los dos tipos (no probado):
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);
}
}
Tal vez es una muleta, pero funciona:
arrayList.Sort(Comparer<object>.Create(
(x, y) => ((RegistryItem)x).Name.CompareTo(((RegistryItem)y).Name)));
Una alternativa al post anterior sería tener tu clase comparador implementar ambas interfaces, entonces usted puede lanzar IComparer
public class MyComparer<T> : IComparer<T>, IComparer
public class BoxedRegistryItemComparer : IComparer {
...
}