c# – 在ICompareable中对接口引用对象的列表进行排序

我在使用list.Sort()时遇到了指向不同类型的接口引用列表的问题,但问题Sort a list of interface objects提供了以下解决方案解决方案

interface IFoo : IComparable<IFoo> 
{ 
    int Value { get; set; } 
}

class SomeFoo : IFoo
{
    public int Value { get; set; }

    public int CompareTo(IFoo other)
    {
        // implement your custom comparison here...
    }
}

在我的原始代码而不是IFoo从IComparable中获取我的课程从IFoo和ICompareable中获取,即

interface IFoo
{ 
    int Value { get; set; } 
}

class SomeFoo : IFoo, IComparable<IFoo> 
{
    public int Value { get; set; }

    public int CompareTo(IFoo other)
    {
        // implement your custom comparison here...

    }
}
class SomeBar : IFoo, IComparable<IFoo> 
{
    public int Value { get; set; }

    public int CompareTo(IFoo other)
    {
        // implement your custom comparison here...
    }
}

但我得到错误无法比较数组中的两个元素.在尝试对IFoo引用列表进行排序时.

List<IFoo> iFoos = new List<IFoo> 
{
    new SomeFoo{Value = 1},
    new SomeFoo{Value = 15},
    new SomeFoo{Value = 390},
    new SomeBar{Value = 2},
    new SomeBar{Value = 78},
    new SomeBar{Value = 134}
}

iFoos.Sort();

任何人都可以解释为什么我的原始代码不起作用?

解决方法:

您的列表是IFoos列表.因此,从列表(及其排序操作)的角度来看,它只能看到该接口,并且对具体类型一无所知.

因此,当它试图订购两个IFoos时,它不能这样做,因为IFoo没有实现IComparable.

问题是因为你的两个类型都实现了IComparable< Foo>另外,不能保证列表中的所有IFoo元素都这样做.所以操作不安全.

为了能够使用IComparable< IFoo>对元素进行排序,IFoo接口需要实现接口本身.

或者,您也可以实现IComparer< IFoo>并将其传递给Sort(),然后将其委托给相应的实际实现.当然,这不是一个优雅的解决方案,也不是未来的证明(如果您创建了一个新的IFoo实现):

class FooComparer : IComparer<IFoo>
{
    public int Compare(IFoo a, IFoo b)
    {
        if (a is SomeFoo)
            return ((SomeFoo)a).CompareTo(b);
        else if (a is SomeBar)
            return ((SomeBar)a).CompareTo(b);
        else
            throw new NotImplementedException("Comparing neither SomeFoo nor SomeBar");
    }
}

当然,如果你的意思是IFoo可以比较,你应该让那个接口实现IComparable< IFoo>直接而不是依靠子类型来做到这一点. IFoo是一份合同,可以排序是一个很好的要求.

上一篇:Android开发 retrofit入门讲解 (RxJava模式)


下一篇:c# – 只需要IComparable的SortedList