Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> C# сравнение экземпляров класса 
V
    Опции темы
Hoborg
Дата 6.6.2011, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 29.1.2009

Репутация: нет
Всего: нет



Как сделать сравнение двух экземпляров класса, один (или оба) из которых может быть null? Применим ли вообще этот вопрос к C#, или я делаю что-то совсем не так?

Чтобы проиллюстрировать вопрос, написал следующий пример. Во время исполнения ошибка, можно сказать, начинается со строки 36.

Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace hate {
    class Book { //Класс "Книга"
        public string title; //Название

        public Book(string newTitle) { //Нормальный конструктор
            title = newTitle;
        }

        public static Book createNullBook() { //Создать книгу, на самом деле являющуюся null
            return null;
        }

        public bool Equals(Book book) { //Сравнение
            return title == book.title;
        }

        public static bool operator ==(Book leftBook, Book rightBook) { //Оператор сравнения
            return leftBook.Equals(rightBook);
        }

        public static bool operator !=(Book leftBook, Book rightBook) { //Оператор сравнения
            return !leftBook.Equals(rightBook);
        }
    }

    class Program {
        static void Main(string[] args) {
            Book 
                LOTR = Book.createNullBook(), 
                HP = new Book("Harry Potter");
            if(LOTR == HP) {} //Сравнить два экземпляра класса, один из которых создан, а другой равен null
        }
    }
}

PM MAIL   Вверх
Экскалупатор
Дата 6.6.2011, 17:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



Object.Equals - метод ???

Это сообщение отредактировал(а) Экскалупатор - 6.6.2011, 17:06
PM MAIL ICQ   Вверх
mihryak
Дата 7.6.2011, 12:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



Цитата(Экскалупатор @  6.6.2011,  18:02 Найти цитируемый пост)
Object.Equals - метод ???

эээ?

Код

    class Book : IEquatable<Book>
    {
        public string Title;

        public bool Equals(Book other)
        {
            return ReferenceEquals(other, null) ? false : Title == other.Title;
        }

        public override bool Equals(object obj)
        {
            return Equals(obj as Book);
        }

        public override int GetHashCode()
        {
            return Title != null ? Title.GetHashCode() : 0;
        }

        public static bool operator ==(Book leftBook, Book rightBook)
        {
            return ReferenceEquals(leftBook, null) ? ReferenceEquals(rightBook, null) : leftBook.Equals(rightBook);
        }

        public static bool operator !=(Book leftBook, Book rightBook)
        {
            return !(leftBook == rightBook);
        }
    }


Добавлено @ 12:13
Цитата(mihryak @  7.6.2011,  13:04 Найти цитируемый пост)
Цитата(Экскалупатор @  6.6.2011,  18:02 Найти цитируемый пост)
Object.Equals - метод ???

эээ?

понял
протите, был напуган smile предполагалось ведь, что Equals(object) тоже будет иметь оверрайд?

Это сообщение отредактировал(а) mihryak - 7.6.2011, 12:14
PM MAIL ICQ   Вверх
Экскалупатор
Дата 7.6.2011, 12:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



там в статье есть пример, в котором как раз таки и сравнивается объект класса с null, при этом возвращается false.
Код

s1 = null;
   s2 = "Tom";
   Console.WriteLine("Object.Equals(null, \"{1}\") => {2}",
       s1, s2, Object.Equals(s1, s2));

зачем его перегружать если можно обратиться к методу класса Object? точнее сделать так что бы Book к нему обращался...
PM MAIL ICQ   Вверх
mihryak
Дата 7.6.2011, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



если не перегрузить Equals, то при вызове статического Object.Equals из ссылки будет вызвана базовая реализация, проверяющая лишь равенство ссылок, а это - совсем не то, что нужно автору
PM MAIL ICQ   Вверх
Экскалупатор
Дата 7.6.2011, 14:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



а что именно нужно автору? там написано только сравнить два экземпляра, и реализовано это через Equals, если нужно сравнивать по значению полей, тогда нет смысла использовать этот метод вообще, его конечно нужно перегрузить, но в перегрузке вызывать его нет смысла, хотя для сравнения с null, можно воспользоваться базовой реализацией, а потом добавить сравнение по содержимому.
PM MAIL ICQ   Вверх
mihryak
Дата 7.6.2011, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 731
Регистрация: 28.4.2007
Где: С-Пб

Репутация: 19
Всего: 36



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

мои соображения таковы:
1. раз перегружаются операторы == и !=, то Equals(object) тоже необходимо перегузить для нормальной работы коллекций и прочих внутренностей фреймворка, которые могут попытаться сравнить два объекта. результат операторов и Equals(object) дожен быть один
2. перегрузка Equals(object) автоматически влечёт за собой необходимость соответственно изменить и GetHashCode()
3. проверять на равенство объектов статическим методом Object.Equals(object, object) приемлимо только при напичии оверрайда Equals(object), т.к. сначала он проверит на null, а потом вызовет этот самый Equals(object) (понятно, что базовая реализация просто тупо сравнит ссылки)
4. лично я, перегружая Equals(object), ещё и помечаю объект интерфейсом IEquatable<Type>, т.к. он может оказаться полезен для коллекций, а реализация уже и так есть
PM MAIL ICQ   Вверх
Экскалупатор
Дата 7.6.2011, 22:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1746
Регистрация: 1.4.2009
Где: г. Минск

Репутация: 11
Всего: 24



mihryak, да, что то я не о том видно думал... видно жара сказывается...
я имел ввиду что можно сравнить Object.Equals и если один из них null то результат будет false, но теперь вижу что автору это не подойдет. в любом случае я думаю в коде автора есть потенциальный косяк, в том что он предполагает, что null может быть только второй экземпляр. т.е. я имею ввиду что перегрузки они статические, т.е. код сравнения запустится в любом случае, а дальше возможно ошибка при попытке вызвать метод экземпляра, если leftBook = null.
а вообще согласен с mihryak, если перегружать то надо перегружать все.
PM MAIL ICQ   Вверх
Hoborg
Дата 9.6.2011, 10:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 29.1.2009

Репутация: нет
Всего: нет



Всё понятно. Спасибо за развёрнутые ответы.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0488 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.