“Non è possibile convertire in IComparer”
Domanda
Ho il seguente IComparer definito per gli oggetti RegistryItem in scatola:
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);
}
}
Voglio usare questo per ordinare un ArrayList di RegistryItems in scatola (in realtà dovrebbe essere un List<RegistryItem
>, ma questo è fuori dal mio controllo).
ArrayList regItems = new ArrayList();
// fill up the list ...
BoxedRegistryItemComparer comparer = new BoxedRegistryItemComparer();
ArrayList.sort(comparer);
Tuttavia, l'ultima linea dà l'errore del compilatore: "Impossibile convertire da BoxedRegistryItemComparer a System.Collections.IComparer". Vi sarei grato se qualcuno potesse sottolineare il mio errore.
Soluzione
BoxedRegistryItemComparer
dovrebbe implementare System.Collections.IComparer
da utilizzare con ArrayList.Sort
. implementato System.Collections.Generic.IComparer<T>
che non è la stessa cosa.
Altri suggerimenti
Hai definito un Generic-Comparer (IComparer<T>
) invece di un Comparer senza un tipo (IComparer
) . ArrayList.Sort()
aspetta una non generica IComparer
.
generic-Tipi non possono essere colate nei loro equivalenti non generici.
Nel caso in cui si dispone di una situazione in cui non si ha alcun controllo sul Comparer o il Sorter, qui ci sono due mini-classi che può convertire tra i due tipi (non testata):
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);
}
}
Forse è una stampella, ma funziona:
arrayList.Sort(Comparer<object>.Create(
(x, y) => ((RegistryItem)x).Name.CompareTo(((RegistryItem)y).Name)));
Un'alternativa al post sopra sarebbe quella di avere la classe di confronto implementare entrambe le interfacce, allora si può lanciare IComparer
public class MyComparer<T> : IComparer<T>, IComparer
public class BoxedRegistryItemComparer : IComparer {
...
}