gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 21:55:50 25 4
gpt4 key购买 nike

例如我有这些类和子类。

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) 在“SortOrder”中对子类组进行排序,因此 Rabbits 在列表中排在第一位,而 Eagles 在最后。

我曾尝试通过实现 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com