Если я правильно понимаю, IComparable
и IComparable<T>
предназначены для определения естественного или полного упорядочения набора типов. В любом случае отношение, определяемое CompareTo(Object)
или CompareTo(T)
, должно быть рефлексивным, симметричным и транзитивным.
Все это очень хорошо и хорошо и вполне применимо, когда применяется к одному типу или даже к целой иерархии типов (предположим, что эти более производные типы не должны влиять на определение отношения). Однако, как только подтип вводит элемент состояния, который должен повлиять на его отношение с точки зрения тех типов, от которых он производен, сравнимые интерфейсы, кажется, почти не работают.
Предоставленный образец кода демонстрирует мое текущее решение проблемы. Поскольку RelationalObject
не может иметь каких-либо знаний о тех типах, которые действительно необходимо сравнивать, его основная цель состоит в том, чтобы в первую очередь предоставить и запечатать модифицируемую реализацию CompareTo
, требуя, чтобы производные типы фактически реализовывали алгоритмы сравнения на основе контекста.
Мне интересно, есть ли лучший метод обработки таких сценариев? Я понимаю, что, вероятно, мог бы просто реализовать некоторые IComparer
или IComparer<T>
, которые знают и могут обрабатывать сравнение известных объектов; однако это, кажется, противоречит цели IComparable
и IComparable<T>
.
using System;
public abstract class RelationalObject : IComparable<RelationalObject>
{
public sealed int CompareTo(RelationalObject that)
{
int relation = 0;
if (that == null)
relation = 1;
if (relation == 0 && !this.Equals(that))
{
Type thisType = this.GetType();
Type thatType = that.GetType();
if (thatType.IsInstanceOfType(this))
{
if (thisType.Equals(thatType))
relation = this.CompareToExactType(that);
else
relation = -1 * that.CompareToSuperType(this);
}
else
{
if (thisType.IsInstanceOfType(that))
relation = this.CompareToSuperType(that);
else
relation = this.CompareToForeignType(that);
}
}
return relation;
}
protected abstract int CompareToExactType(RelationalObject that);
protected abstract int CompareToForeignType(RelationalObject that);
protected abstract int CompareToSuperType(RelationalObject that);
}