这比其他任何事情都更具学术性,因此我基本上只是想弄清楚类型不同时如何使用IComparable。
因此,我们有一个水果类,以及派生类“ Apple”和“ Orange”。假设我要列出一个水果清单,使所有苹果都位于橙子之前。最好的方法是什么?
我认为您可以使Fruit实现IComparable接口,并为非常子类型放入一堆条件语句,但是对我来说,这似乎很粗糙,并且可能违反了开放/封闭原则。我对使它以这种方式工作更感兴趣:
public abstract class Fruit : IComparable<Fruit>
{
public abstract int CompareTo(Fruit other);
}
public class Apple : Fruit, IComparable<Orange>
{
public override int CompareTo(Fruit other)
{
if(other is Orange)
{
this.CompareTo((Orange)other);
}
return 0;
}
public virtual int CompareTo(Orange other)
{
return -1;
}
}
public class Orange : Fruit, IComparable<Apple>
{
public override int CompareTo(Fruit other)
{
if (other is Apple)
{
this.CompareTo((Apple)other);
}
return 0;
}
public virtual int CompareTo(Apple other)
{
return 1;
}
}
我在这里的主要目标是让IComparable处理交叉类型。我尝试加载各种水果的清单,但可惜没有排序。也许我对CompareTo的返回值的理解有些奇怪。这种方法是否有希望,是否存在比明显方法有用的任何场景?
答案 0 :(得分:1)
它将立即变得可怕...每个水果都必须彼此了解...如果您有10个水果,则有90条代码来决定如何比较它们。
我会做类似的事情:
public abstract class Fruit : IComparable<Fruit>
{
// It should be unique for each fruit type
public abstract int Importance { get; }
public int CompareTo(Fruit other)
{
// If you want, you can do some tests here, that
// are common to all the Fruit. I wouldn't,
// because this would create an ordering with
// higher priority than Importance.
int cmp = Importance.CompareTo(other.Importance);
if (cmp != 0)
{
return cmp;
}
if (GetType() != other.GetType())
{
throw new ApplicationException("Different type of fruit must have different Importance");
}
// Other Fruit comparisons
// We know the Fruit have the same type (see above)
return CompareToInternal(other);
}
// Comparison of subtype of Fruit
public abstract int CompareToInternal(Fruit other);
}
因此,只有相同类型的Fruit
是可比较的。其他水果的Importance
是预先确定的(苹果比猕猴桃好),还有一个抽象的CompareToInternal
用于进行子类型比较(在同一类型的水果中……苹果与苹果,奇异果与猕猴桃)
答案 1 :(得分:1)
我觉得这有点奇怪,因为苹果和橘子没有天然的顺序。 在这种特定情况下,您更喜欢苹果而不是橘子,但也许下一个家伙反过来想要它。还是在冬天混合?关键是苹果和橘子没有一个独特的排序算法,将其构建到苹果,橘子甚至水果中都是错误的。
这就是IComparer
的用处。您可以在其中放置比较逻辑,但是可以有许多个比较器,并根据每种排序选择另一个。因此,您在冬季实施了ApplesFirstComparer
,然后实施了OrangesWithTheMostOrangeColorOnTopDoNotCareForColorOfApplesComparer
和另一个。基本上,您需要进行的每个比较都需要一个,而不意味着苹果和橘子具有自然的顺序。因为他们没有。
答案 2 :(得分:1)
这是我的主意。看起来很简单,但是可以正常工作。
您可以标记每个类的唯一顺序并将其排序。
public abstract class Fruit
{
public int MyOrder {get;}
}
public class Apple : Fruit
{
}
public class Orange : Fruit
{
}
现在,您想要所有的苹果都比橘子先。设置值并对其进行排序。
//Suppose that this is your list fruits
var fruits = new List<Fruit>();
fruits.OfType<Apple>().ForEach(a=> a.MyOrder = 1);
fruits.OfType<Orange>().ForEach(a=> a.MyOrder = 2);
var sorted = fruits.OrderBy(x=>MyOrder);
如果您有多个水果,那将是一个不利条件。
但是如果您的订单没有变化,就像苹果总是比橙子先。在课堂上设置MyOrder
。
public abstract class Fruit
{
public abstract int MyOrder {get;}
}
public class Apple : Fruit
{
public override int MyOrder {
get { return 1;}
}
}
public class Orange : Fruit
{
public override int MyOrder {
get { return 2;}
}
}