Реализация IEquatable, где T-интерфейс
у меня есть модель домена, которая тривиально представлена следующим.
IMyInterface
ClassA : IMyInterface
ClassB : IMyInterface
Я хочу реализовать IEquatable таким образом, чтобы я мог написать код что-то вроде.
if(dynamicallyCreatedInstanceOfClassA == dynamicallyCreatedinstanceOfClassB)
{
// Do something relevant
}
моей первой склонностью было иметь imyinterface реализовать IEquatable, но, конечно, я не могу фактически выполнить реализацию в IMyInterface. Я должен был бы сделать это в ClassA и ClassB. Что меня поражает в этом решении, так это то, что реализации IEquatable в ClassA и ClassB будут точно, строка для строки то же самое. Есть ли элегантный способ добиться этого? Когда приходит ClassC, я не хочу копировать и мимо 50 строк дублированного IEquatable кода.
Я рассматривал использование абстрактного базового класса вместо интерфейса, но в этом сценарии IMyInterface действительно просто описывает действия, которые класс будет выполнять, а не то, что класс. ClassA и ClassB не имеют много общего, за исключением того, что они могут выполнять действия в контракте IMyInterface.
любые идеи полезны, и спасибо за ваше время.
4 ответов
вместо реализации IEquatable<T>
, не могли бы вы реализовать IEqualityComparer<T>
в отдельный класс? В большинстве случаев, когда вы заинтересованы в равенстве, вы можете указать компаратор, и я подозреваю, что это будет чище.
основываясь на вашем вопросе, кажется, что вы знаете, каким будет алгоритм Equals и что он будет точно таким же для ClassA и ClassB. Почему бы не сделать следующее
- определите IMyInterface для наследования от
IEquatable<IMyInterface>
- определите абстрактный базовый класс MyInterfaceBase, который реализует IMyInterface и имеет
IEquatable<IMyInterface>
реализация - имеют ClassA и ClassB производные от MyInterfaceBase
если IEquatable<T>
включил GetHashcode()
member возможно определить значимую семантику для того типа, который отличается от Object.Equals
(например, " если бы вы смотрели только на характеристики, которые присутствуют в T
, будут ли объекты считаться одинаковыми"). Поскольку это не так, однако, обычно нет особых причин для реализации IEquatable<T>
за исключением тех случаев, когда он может улучшить производительность без добавления какой-либо причудливой семантики. На практике это означает, что IEquatable<T>
должны либо реализовываться только (Если T
является запечатанным классом или структурой), или нет вообще (если T
наследуется, или если преимущества производительности не стоят усилий).
Я бы подумал, что если интерфейс не может быть преобразован в абстрактный класс, нет смысла сравнивать два реализованных класса друг с другом напрямую или автоматически. Это означает, что реализация пользовательского сравнения для каждого класса будет способом. Я уверен, что вы можете как-то рефакторинг кода сравнения, для того чтобы сделать изменяя его легче позже.