1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
||||||||||||||||
1 | ||||||||||||||||
Перегрузить оператор ==, но не потерять возможности сравнения с null11.07.2012, 16:13. Показов 7342. Ответов 17
Метки нет (Все метки)
Как перегрузить оператор == для класса, но так чтобы проверка на null осталась работоспособной.
Потому как если я перегружаю оператор == в классе
0
|
11.07.2012, 16:13 | |
Ответы с готовыми решениями:
17
Не получается перегрузить оператор сравнения Для шаблонного класса перегрузить оператор присваивания, copy-конструктор, объекты cin и cout, оператор * Перегрузить операторы сравнения и отсортировать Как перегрузить оператор<< и оператор>> ? |
Master of Orion
|
||||||
11.07.2012, 16:18 | 2 | |||||
Gepar,
2
|
267 / 257 / 43
Регистрация: 18.03.2012
Сообщений: 506
|
||||||
11.07.2012, 16:55 | 4 | |||||
Один из вариантов - приведение к object для сравнения, как предложил Psilon.
Еще возможно использование ReferenceEquals:
2
|
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
||||||||||||||||
11.07.2012, 17:08 [ТС] | 5 | |||||||||||||||
buntar, и что же ты изменил? Проверку то оставил ту же самую.
Psilon, твой вариант тоже не работает, по прежнему будет ошибка получаться. Приведу ка я весь код наверное. Код весьма прост, хоть и не очень короткий, это учебный пример так что допустимость значений проверяется только там где это важно для работоспособности кода, а не корректности результатов. Проблема возникает лишь с оператором == и последующим его (случайным) использованием при сравнении с null. 1) Вариант который собирается (оператор == и != закомментирован потому и собирается !)
Добавлено через 4 минуты С ReferenceEquals сработало. Перегрузка приняла вид
Добавлено через 2 минуты Хотя с приведениями к Object тоже сработало, нужно только обе проверки было сделать чтобы было так:
0
|
Master of Orion
|
||||||
11.07.2012, 17:08 | 6 | |||||
0
|
Gepar
|
11.07.2012, 17:08
[ТС]
#7
|
Не по теме: deleted
0
|
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
|
|
11.07.2012, 17:13 | 9 |
Не забудьте также переопределить метод Equals и GetHashCode, чтобы не было неоднозначности в сравнении двух экземпляров.
0
|
267 / 257 / 43
Регистрация: 18.03.2012
Сообщений: 506
|
||||||
11.07.2012, 17:19 | 10 | |||||
Зачем столько if - ов и else -ов. Мой код уже проверял все возможности:
Если уж переопределять Object.Equals, то правильнее будет писать и Equals интерфейса IEquatable<Person>. А в этом случае, оператор сравнения, лучше уже переписывать на его основе...
0
|
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
|
|
11.07.2012, 17:23 | 11 |
Не правильнее.
IEquatable и метод Equals класса object - это разные вещи. По гайдлайнам при перегрузке оператора == и !=, также нужно переопределять метод Equals и GetHashCode - именно для постоянства реализации. Если же хочется внести дополнительное понятие "равенства" или "эквивалентности" объектов, тогда уже можно реализовать IEquatable.
0
|
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
|
11.07.2012, 17:33 [ТС] | 12 |
Класс не претендует на "доделанный, протестированный и быстро работающий", как видите там и ToString() не перегружено даже для вывода объектов класса, я перфекционизмом не страдаю
Вот тут кстати интересная вещь: код собирался и не жаловался ни на что, но стоило мне попытаться добавить ещё итерацию по Возрастам (Ages), те просто левую функцию возвращающую IEnumerator (то что добавил кстати не хочет вызываться ещё как планировал, но не суть), как VS внезапно вспомнила что я оператор == и != перегрузил, а вот Equals и GetHaskCode - нет. А ведь до этого молчала же.
0
|
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
|
|
11.07.2012, 17:36 | 13 |
А класс и не должен на это претендовать.
На то, чтобы класс таковым являлся, должны претендовать вы, как разработчик этого класса. В противном случае - вон из профессии Студия этим грешит время от времени. Я пока точно не понял: что-то в коде не так или студийный парсер глючит, но тоже не раз замечал, что некоторые ворнинги генерируются при одном билде и пропадают на другом (без изменения кода).
1
|
1186 / 542 / 78
Регистрация: 01.07.2009
Сообщений: 3,517
|
|
11.07.2012, 17:49 [ТС] | 14 |
Я ленивый, попробовал пару раз перегрузить ToString() - получилось нормально вот и перестал перегружать во всех остальных классах заостряя внимание на ту тему которая описывается в текущей главе книги, в данном случае перегрузка операторов и итераторы. С остальным тоже самое, лень реализовывать по 100 раз тоже самое если это всего лишь учебный пример и он никому после его написания не понадобится.
А, ну тогда всё в порядке, ато я уже подумал было что в с# есть какой-то хитрый таракан в стиле "если у вас процессор Intel, а количество функций в классе больше 5 и вы перегрузили оператор == то вы обязаны перегрузить ещё и ...". Мало ли
0
|
267 / 257 / 43
Регистрация: 18.03.2012
Сообщений: 506
|
||||||
11.07.2012, 17:49 | 15 | |||||
Если уж говорить о гайдлайнах - не так давно интересовался как нужно правильно использовать все возможные методы сравнения (static object.Equals, instance object.Equals, ReferenceEquals, Equals<T>, ==, !=). В итоге, побродив по просторам интернета, в частности по StackOverflow, наткнулся на книгу Effective C# в которой в деталях расписывался, в том числе, этот момент. Так вот, ее автор прямо настаивает на использовании обобщенного Equals в случае переопределения обычного.
В частности, он приводит следующую реализацию object.Equals:
0
|
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
|
|
11.07.2012, 18:03 | 16 |
Вполне может быть, что он действительно есть.
Но что студия время от времени, казалось бы, без причины то выдает, то не выдает ворнинги - случается. Ну это примерно то же самое, что рекомендации вместе с интерфейсом IEnumerable<T> реализовывать так же IEnumerable. Они отнюдь не лишены смысла, но студия ругаться не будет, если их оба не реализовывать. Я один и тот же тип имел в виду. Конечно, если при разных обстоятельствах условия эквивалентности меняются, то тут лучше писать отдельный класс, реализующий IEqualityComparer для каждого условия.
0
|
267 / 257 / 43
Регистрация: 18.03.2012
Сообщений: 506
|
|
11.07.2012, 18:27 | 17 |
Или я вас не понял, или вы меня... Под словами
я имел в виду следующее:
если мы перегружаем object.Equals(object obj), то ,чаще всего, попросту осуществляется попытка свести obj к типу нашего класса MyClass и потом производить нужные сравнения. Так вот логичнее всего вынести эти сравнения в Equals(MyClass obj). Разве IEnumerable<T> не наследует IEnumerable? Кроме того, ругань студии охватывает довольно мало ситуаций... Например, у мелкомягких есть рекомендации по добавлению дополнительного статического метода для любого перегруженного оператора, но студия даже не заикается об этом...
0
|
17685 / 12871 / 3365
Регистрация: 17.09.2011
Сообщений: 21,136
|
|
11.07.2012, 19:08 | 18 |
Так точно. Для этого дела даже паттерн есть.
Полностью с вами согласен. Но проблема возникает тогда, когда мы пытаемся наш сферический класс в вакууме, реализовавший IEquatable<MyClass>, передать ссылочкой в какой-нибудь метод, написанный до появления генериков (которых во фреймворке - пруд пруди). Этот метод будет использовать Equals, определенный у object, а мы будем наблюдать странную работу приложения и чесать репу, размышляя, что за фигня тут творится Наследует. Я, честно сказать, тоже не вижу причину в такой рекомендации. Возможно, возникают какие-то сложности или непонятки в случае наследования и перереализации наследником этого интерфейса - вот и сделали из частного случая общую рекомендацию. Но это так - мои домыслы о действительных причинах. Полезные рекомендации, кстати. Но, говоря конкретно о ругани, - это рекомендации для написания CLS-compliant кода. Если вы пометите класс, перегружающий операторы, как CLS-compliant, то, я думаю, студия будет ругаться.
1
|
11.07.2012, 19:08 | |
11.07.2012, 19:08 | |
Помогаю со студенческими работами здесь
18
Проиллюстрировать возможности операций отношения (сравнения) Для класса Vector перегрузить операторы присваивания, сравнения, ввода и вывода Как перегрузить методы Equals() и GetHashCode(), для сравнения свойств объектов? Как перегрузить операции отношения для реализации значимой семантики сравнения объектов Перегрузить оператор - Перегрузить оператор Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |