Реализация 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. Почему бы не сделать следующее

  1. определите IMyInterface для наследования от IEquatable<IMyInterface>
  2. определите абстрактный базовый класс MyInterfaceBase, который реализует IMyInterface и имеет IEquatable<IMyInterface> реализация
  3. имеют ClassA и ClassB производные от MyInterfaceBase

если IEquatable<T> включил GetHashcode() member возможно определить значимую семантику для того типа, который отличается от Object.Equals (например, " если бы вы смотрели только на характеристики, которые присутствуют в T, будут ли объекты считаться одинаковыми"). Поскольку это не так, однако, обычно нет особых причин для реализации IEquatable<T> за исключением тех случаев, когда он может улучшить производительность без добавления какой-либо причудливой семантики. На практике это означает, что IEquatable<T> должны либо реализовываться только (Если T является запечатанным классом или структурой), или нет вообще (если T наследуется, или если преимущества производительности не стоят усилий).


Я бы подумал, что если интерфейс не может быть преобразован в абстрактный класс, нет смысла сравнивать два реализованных класса друг с другом напрямую или автоматически. Это означает, что реализация пользовательского сравнения для каждого класса будет способом. Я уверен, что вы можете как-то рефакторинг кода сравнения, для того чтобы сделать изменяя его легче позже.