猿问

比较“Apple”和“Orange”对象列表

这更像是一种学术练习,所以我基本上只是想弄清楚当类型不同时如何使用 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 的返回值的理解有点不稳定。这种类型的方法是否有任何希望,是否有任何场景比显而易见的方法更有用?


德玛西亚99
浏览 260回答 3
3回答

撒科打诨

我认为这感觉有点不稳定,因为苹果和橙子没有自然顺序。在这个特定的例子中,你更喜欢苹果而不是橘子,但也许下一个人想要相反。还是冬天混搭?关键是 Apples 和 Oranges 没有一种独特的排序算法,将它构建到 Apples 或 Oranges 甚至水果中感觉是错误的。这就是IComparer进来的地方。你可以把你的比较逻辑放在那里,但你可以有很多比较器,并在你做的每一种排序中选择另一个。所以你ApplesFirstComparer在冬天实施了一个,然后一个OrangesWithTheMostOrangeColorOnTopDoNotCareForColorOfApplesComparer又一个,另一个又一个。基本上每个比较你需要一个,而不意味着苹果和橙子有一个自然的顺序。因为他们没有。

动漫人物

这是我的想法。这看起来很简单,但它会起作用。您可以为每个类标记唯一的顺序并对其进行排序。public abstract class Fruit{&nbsp; &nbsp; public int MyOrder {get;}}public class Apple : Fruit{&nbsp; &nbsp;&nbsp;}public class Orange : Fruit{&nbsp; &nbsp;&nbsp;}现在,你想要在橙子之前的所有苹果。设置值并对其进行排序。//Suppose that this is your list fruitsvar 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在课堂上设置。&nbsp; &nbsp; public abstract class Fruit&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; public abstract int MyOrder {get;}&nbsp; &nbsp; }&nbsp; &nbsp; public class Apple : Fruit&nbsp; &nbsp; {&nbsp; &nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; public override int MyOrder {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get { return 1;}&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }&nbsp; &nbsp; public class Orange : Fruit&nbsp; &nbsp; {&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; public override int MyOrder {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; get { return 2;}&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp;&nbsp;&nbsp; &nbsp; }

当年话下

马上就变得很可怕了……每个水果都必须知道彼此的水果……如果你有10个水果,你有90段代码只是为了决定如何比较它们。我会做这样的事情:public abstract class Fruit : IComparable<Fruit>{&nbsp; &nbsp; // It should be unique for each fruit type&nbsp; &nbsp; public abstract int Importance { get; }&nbsp; &nbsp; public int CompareTo(Fruit other)&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; // If you want, you can do some tests here, that&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; // are common to all the Fruit. I wouldn't,&nbsp; &nbsp; &nbsp; &nbsp; // because this would create an ordering with&nbsp; &nbsp; &nbsp; &nbsp; // higher priority than Importance.&nbsp; &nbsp; &nbsp; &nbsp; int cmp = Importance.CompareTo(other.Importance);&nbsp; &nbsp; &nbsp; &nbsp; if (cmp != 0)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return cmp;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; if (GetType() != other.GetType())&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; throw new ApplicationException("Different type of fruit must have different Importance");&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; // Other Fruit comparisons&nbsp; &nbsp; &nbsp; &nbsp; // We know the Fruit have the same type (see above)&nbsp; &nbsp; &nbsp; &nbsp; return CompareToInternal(other);&nbsp; &nbsp; }&nbsp; &nbsp; // Comparison of subtype of Fruit&nbsp; &nbsp; public abstract int CompareToInternal(Fruit other);}所以只有Fruit同类型的才真正具有可比性。其他水果有一个Importance预先确定的(苹果比猕猴桃好),并且有一个摘要CompareToInternal来进行子类型比较(在同一类型的水果中......苹果vs苹果,猕猴桃vs猕猴桃)
随时随地看视频慕课网APP
我要回答