为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
德玛西亚99 2021-10-31 19:00:04
这更像是一种学术练习,所以我基本上只是想弄清楚当类型不同时如何使用 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 的返回值的理解有点不稳定。这种类型的方法是否有任何希望,是否有任何场景比显而易见的方法更有用?
查看完整描述

3 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

我认为这感觉有点不稳定,因为苹果和橙子没有自然顺序。在这个特定的例子中,你更喜欢苹果而不是橘子,但也许下一个人想要相反。还是冬天混搭?关键是 Apples 和 Oranges 没有一种独特的排序算法,将它构建到 Apples 或 Oranges 甚至水果中感觉是错误的。

这就是IComparer进来的地方。你可以把你的比较逻辑放在那里,但你可以有很多比较器,并在你做的每一种排序中选择另一个。所以你ApplesFirstComparer在冬天实施了一个,然后一个OrangesWithTheMostOrangeColorOnTopDoNotCareForColorOfApplesComparer又一个,另一个又一个。基本上每个比较你需要一个,而不意味着苹果和橙子有一个自然的顺序。因为他们没有。


查看完整回答
反对 回复 2021-10-31
?
动漫人物

TA贡献1815条经验 获得超10个赞

这是我的想法。这看起来很简单,但它会起作用。


您可以为每个类标记唯一的顺序并对其进行排序。


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;}

        }  

    }


查看完整回答
反对 回复 2021-10-31
?
当年话下

TA贡献1890条经验 获得超9个赞

马上就变得很可怕了……每个水果都必须知道彼此的水果……如果你有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来进行子类型比较(在同一类型的水果中......苹果vs苹果,猕猴桃vs猕猴桃)


查看完整回答
反对 回复 2021-10-31
  • 3 回答
  • 0 关注
  • 259 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信