我在使用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是一份合同,可以排序是一个很好的要求.