Интересно, будет ли у вас такой же вопрос, если бы MyClass
реализовал IComparable<MyClass>
вместо или (или, может быть, так же, как) IComparable
Давайте сделаем тот же вопрос с менее абстрактным примером.
Предположим, у нас есть класс Animal
. Каждое животное имеет NumberOfLegs
. Мы хотели бы заказать животных на это количество ног, поэтому мы реализуем IComparable<Animal>
.
Предположим, у нас также есть класс Human, производный от Animal
(хотя некоторые будут сомневаться в этом). Каждый Human
имеет Name
, и мы хотели бы заказать Humans
по имени, поэтому мы реализуем IComparable<Human>
Точно так же у нас есть Spider
, который, конечно, является восьминогим Animal
:
class Animal : IComparable<Animal> {...}
class Spider : Animal, IComparable<Spider> {...}
class Human : Animal, IComparable<Human> {...}
Легко ответить будет следующее: каковы значения x и y?
Animal spider = new Spider();
Animal bill = new Human("William Shakespeare");
int x = spider.CompareTo(bill); // +1 A spider has more legs than bill
int y = bill.CompareTo(spider); // -1: bill has less legs than Spider
Давайте сделаем это снова: каково значение z?
Spider spider = new Spider();
Human bill = new Human("William Shakespeare");
int z = bill.CompareTo(spider); // ???
Каким вам хотелось бы быть значение этого ? Класс Human
не реализует IComparable<Spider>
, и не все Пауки имеют имя. Таким образом, все, что мы можем сделать, это сравнить по количеству ног, что и произойдет.
Если вам действительно нужна особая обработка при сравнении людей и пауков (например, с помощью фактора страха), вы должны позволить человеку реализовать IComparable<Spider>
(или наоборот).
Теперь, когда вы точно знаете, что будете делать, когда будете внедрять IComparable<Human>
, IComparable<Animal>
и т. Д. Я думаю, вы будете знать, что делать, если вы также внедрите IComparable
Последнее замечание : Реализуйте IComparable<...>
только для класса, если ваш метод сравнения типичен для объектов класса. Это если все скажут, что ваш метод - это естественный способ упорядочения объектов такого типа.
Это не естественный способ заказывать животных по количеству ног. Поэтому читатели не будут инстинктивно знать, что сделают следующее:
IEnumerable<Animal> myAnimals = ...
var result = myAnimals.OrderBy(animal => animal);
Animal не должен был реализовывать IComparable подобным образом. Мы должны создать специальный класс Comparer, который реализует IComparer<Animal>
для количества ветвей:
class AnimalLegCountCompare: IComparer<Animal> {...}
Следующее будет менее запутанным для читателей:
ICompared<Animal> legCountComparer = new AnimalLegCountComparer();
var result = myAnimals
.OrderBy(animal=>animal, legCountComparer);