c# - 如何对子类进行比较和排序?

标签 c# sorting compare subclass

例如,我有这些类和子类。

class Program
{
    static void Main(string[] args)
    {
        var animals = new List<Animal> { new Wolf {kills = 5}, 
                                         new Rabbit {name = "Uncle John"}, 
                                         new Eagle {eyeCount = 1}, 
                                         new Wolf {kills = 100}, 
                                         new Rabbit { name = "Human" } };
        animals.Sort();
//Suposted to be: Rabbit(Human), Rabbit(Uncle John), Wolf(5), Wolf(100), Eagle(1)
    }
}

enum SortOrder { Rabbit, Wolf, Eagle }

abstract class Animal{}
class Wolf : Animal
{
    public int kills = 0; //Marked public for simple initialization
}
class Rabbit : Animal
{
    public string name = "Funny Little Guy"; //Marked public for simple initialization
}
class Eagle : Animal
{
    public byte eyeCount = 2; //Marked public for simple initialization
}

我想对动物列表进行排序。 1) 对相同类型的其他对象进行排序(按杀死次数对狼进行排序,按名称对兔子进行排序,等等) 2) 在“排序顺序”中对子类组进行排序,因此兔子在列表中排在第一位,老鹰排在最后。

我尝试通过实现 IComparable<Animal>, IComparable<Wolf>, IComparable<Rabbit>, IComparable<Eagle> 来做到这一点接口(interface),但这让我无处可去,因为我无法完成这项工作,即使我可以,添加 1 个子类会导致大量代码工作。

这是我的尝试:

abstract class Animal : IComparable<Animal>, IComparable<Wolf>, IComparable<Rabbit>, IComparable<Eagle>
{
    public abstract int CompareTo(Animal other);
    public abstract int CompareTo(Wolf other);
    public abstract int CompareTo(Rabbit other);
    public abstract int CompareTo(Eagle other);
}

class Wolf : Animal
{
    public int kills = 0; //Marked public for simple initialization

    public override int CompareTo(Animal other) => other.CompareTo(this);
    public override int CompareTo(Wolf other) => kills.CompareTo(kills);
    public override int CompareTo(Rabbit other) => SortOrder.Wolf.CompareTo(SortOrder.Rabbit);
    public override int CompareTo(Eagle other) => SortOrder.Wolf.CompareTo(SortOrder.Eagle);
}

但是通过这样做,我得到了相反的顺序,正如我所说,很难添加新的子类。

那么进行这种比较的有效方法是什么?

最佳答案

为了尽量减少添加新代码并强制新类添加到层次结构中,我会进行这种设计:

首先,我将为每种具体动物类型实现 IComparable。这很简单。其次,我会将 SortOrder OrderType 属性添加到抽象类中,并在每个具体实例中实现它。这将迫使任何扩展该类的人重新评估枚举,并可能为其添加新的值。然后,主比较函数将首先检查该属性。如果不相等,则返回类型之间的比较。如果相等,只需对两个实例调用比较,因为可以安全地假设它们具有相同的类型。

在这里实现它。我实际上不得不使用反射,因为没有其他方法来调用具体比较器。但它似乎工作得很好,只要实际类型对应于返回的枚举。

enum SortOrder { Rabbit, Wolf, Eagle }

abstract class Animal : IComparable<Animal>
{
    public abstract SortOrder OrderType { get; }

    public int CompareGeneric(Animal x, Animal y)
    {
        // use reflection to call comparer on concrete animal type
        var comparerType = typeof(IComparable<>).MakeGenericType(x.GetType());
        var compareMethod = comparerType.GetMethod("CompareTo");

        return (int)compareMethod.Invoke(x, new object[] { y });
    }

    public int Compare(Animal x, Animal y)
    {
        // clever hack to compare the enums
        var diff = x.OrderType - y.OrderType;
        if (diff != 0)
            return diff;

        return CompareGeneric(x, y);
    }

    public int CompareTo(Animal other)
    {
        return Compare(this, other);
    }
}

class Wolf : Animal, IComparable<Wolf>
{
    public override SortOrder OrderType { get { return SortOrder.Wolf; } }

    public int kills = 0; //Marked public for simple initialization

    public int CompareTo(Wolf other)
    {
        return this.kills.CompareTo(other.kills);
    }
}
class Rabbit : Animal, IComparable<Rabbit>
{
    public override SortOrder OrderType { get { return SortOrder.Rabbit; } }

    public string name = "Funny Little Guy"; //Marked public for simple initialization

    public int CompareTo(Rabbit other)
    {
        return this.name.CompareTo(other.name);
    }
}
class Eagle : Animal, IComparable<Eagle>
{
    public override SortOrder OrderType { get { return SortOrder.Eagle; } }

    public byte eyeCount = 2; //Marked public for simple initialization

    public int CompareTo(Eagle other)
    {
        return this.eyeCount.CompareTo(other.eyeCount);
    }
}

关于c# - 如何对子类进行比较和排序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31908787/

相关文章:

c# - 使用正则表达式在 c# 中突出显示 CSS 语法

java - 在 Java 中实现选择排序

C# 查找两个字符串之间匹配单词的百分比

Python嵌套字典比较算法

path - 通过有向图比较有向路径相似度的算法

c# - 在没有 toUpper/toLower 的情况下大写/小写字符串的最有效方法

c# - 从其他进程向 WPF 单例应用程序发送数据

c# - 在 Asp.net 中检查数据读取器是否有行

java - 在 Java 中按值映射自动排序

arrays - 使用排序对数组数组进行升序和降序排序