Как реализовывать операторы сравнения в данно случае ???
От:
Аноним
Дата:
30.07.10 11:12
Оценка:
Существует проблема связанная с реализацией оператора == в цепочке наследования из нескольких классов. Например, есть базовый класс A и производный B. Тогда при реализации == в классе А придется реализовать один оператор вида operator==(A, A), а в производном классе B уже три оператора вида: operator==(A, B), operator==(B, A) и operator==(B, B). Рассуждая аналогичным образом для класса C наследника B, потребуется реализовать уже пять операторов. А для класса D наследника C уже девять !!!
Зачем их реализовывать, а как производить сравнения типа A == B или A == C? Определение оператора преобразования в/из базового класса в C# запрещены, поэтому выполняя сравнение A == B, будет вызван operator==(A, A), который сравнит общие для A и B поля и на этом основании сделает вывод о равенстве или не равенстве A и B, т.е. равными могут оказаться объекты разных классов. Что в некоторых случаях вообще неприемлемо! В связи с этим вопрос: как можно решить эту проблему Ведь если в цепочке наследования 5-ть классов, то в последнем понадобиться реализовать уже 11 операторов сравнения !!!
Хотелось бы этого избежать
Re: Как реализовывать операторы сравнения в данно случае ???
Здравствуйте, Аноним, Вы писали:
А>Существует проблема связанная с реализацией оператора == в цепочке наследования из нескольких классов. Например, есть базовый класс A и производный B. Тогда при реализации == в классе А придется реализовать один оператор вида operator==(A, A), а в производном классе B уже три оператора вида: operator==(A, B), operator==(B, A) и operator==(B, B). Рассуждая аналогичным образом для класса C наследника B, потребуется реализовать уже пять операторов. А для класса D наследника C уже девять !!!
Достаточно реализовать в каждом из наследников Object::Equals(object) и operator==(A, A) в классе A.
Help will always be given at Hogwarts to those who ask for it.
Re[2]: Как реализовывать операторы сравнения в данно случае
Здравствуйте, _FRED_, Вы писали:
_FR>Достаточно реализовать в каждом из наследников Object::Equals(object) и operator==(A, A) в классе A.
На всякий случай уточню, что если типы — value types, и предполагается сравнение большого количества объектов, то лучше еще добавить метод Equals(ConcreteType t), чтобы не было боксинга.
Re[3]: Как реализовывать операторы сравнения в данно случае
Здравствуйте, MozgC, Вы писали:
_FR>>Достаточно реализовать в каждом из наследников Object::Equals(object) и operator==(A, A) в классе A.
MC>На всякий случай уточню, что если типы — value types, и предполагается сравнение большого количества объектов, то лучше еще добавить метод Equals(ConcreteType t), чтобы не было боксинга.
Тогда уж и я немного уточню: температура сегодня у нас тёплая, а ответ мой предназначался на вопрос:
Существует проблема связанная с реализацией оператора == в цепочке наследования из нескольких классов…
Help will always be given at Hogwarts to those who ask for it.
Re[4]: Как реализовывать операторы сравнения в данно случае
Здравствуйте, _FRED_, Вы писали:
А>>Существует проблема связанная с реализацией оператора == в цепочке наследования из нескольких классов…
_FR>Достаточно реализовать в каждом из наследников Object::Equals(object) и operator==(A, A) в классе A.
Хотя, в некоторых случаях лучше поступить как-то совсем по-другому. Так что, однозначного ответа на вопрос "как реализовать сравнение в иерархии объектов" не имея на руках таблицы истинности (aka "подробнейшая спецификация") нельзя.
_FR>… и operator==(A, A) в классе A.
А это верно. Причём реализация оператора примитивнейшая:
public static bool operator ==(A left, A right) {
return Equals(left, right);
}
Help will always be given at Hogwarts to those who ask for it.
Re: Как реализовывать операторы сравнения в данно случае ???
Здравствуйте, Аноним, Вы писали:
А>Существует проблема связанная с реализацией оператора == в цепочке наследования из нескольких классов.
Нет, этой проблемы не существует. А>Зачем их реализовывать, а как производить сравнения типа A == B или A == C? Определение оператора преобразования в/из базового класса в C# запрещены, поэтому выполняя сравнение A == B, будет вызван operator==(A, A), который сравнит общие для A и B поля и на этом основании сделает вывод о равенстве или не равенстве A и B, т.е. равными могут оказаться объекты разных классов.
Ну, это если оператор ==(A, A) реализован некорректно. Корректная реализация начнёт с того, что вызовет у обоих аргументов GetType() и сравнит результаты.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re: Как реализовывать операторы сравнения в данно случае ???
Здравствуйте, Аноним, Вы писали:
А>Существует проблема связанная с реализацией оператора == в цепочке наследования из нескольких классов. Например, есть базовый класс A и производный B. Тогда при реализации == в классе А придется реализовать один оператор вида operator==(A, A), а в производном классе B уже три оператора вида: operator==(A, B), operator==(B, A) и operator==(B, B). Рассуждая аналогичным образом для класса C наследника B, потребуется реализовать уже пять операторов. А для класса D наследника C уже девять !!! А>Зачем их реализовывать, а как производить сравнения типа A == B или A == C? Определение оператора преобразования в/из базового класса в C# запрещены, поэтому выполняя сравнение A == B, будет вызван operator==(A, A), который сравнит общие для A и B поля и на этом основании сделает вывод о равенстве или не равенстве A и B, т.е. равными могут оказаться объекты разных классов. Что в некоторых случаях вообще неприемлемо! В связи с этим вопрос: как можно решить эту проблему Ведь если в цепочке наследования 5-ть классов, то в последнем понадобиться реализовать уже 11 операторов сравнения !!! А>Хотелось бы этого избежать
Если нужно сравнивать любой тип иерархии с любым, то нужно рассмотреть количество случаев равное числу сочетаний из N по 2. Если для каждого случая сделать метод, то диспетчеризовать это можно визитором.
А вот связываться с оператором ==, и тем более object.Equals(object), я не рекомендую. Например, захотите узнать, содержится ли данный класс в неком контейнере, и получите неожиданный ответ... Экземпляр класса B может согласно этой логике содержаться в массиве из экземпляров типа A при использовании штатных методов поиска в массиве. И для того чтобы узнать наверняка, придется реализовывать методы поиска через ReferenceEquals.
Re[2]: Как реализовывать операторы сравнения в данно случае
Здравствуйте, samius, Вы писали:
S>Если нужно сравнивать любой тип иерархии с любым, то нужно рассмотреть количество случаев равное числу сочетаний из N по 2.
Да только, сочетаний с повторениями из N по 2