Является ли Nullable <T>.Equals неправильной реализацией метода? - PullRequest
2 голосов
/ 09 октября 2009

Я говорю о языке C # здесь.

Определение метода Object.Equals (Object) в msdn :

Определяет, является ли указанный Объект равен текущему объекту.

Если два объекта равны, он возвращает истину, однако, если они равны нулю, он возвращает ложь:

x.Equals (пустая ссылка (ничего в Visual Basic)) возвращает false.

Почему? Потому что нуль не является объектом.

Выдается исключение NullReferenceException, если параметр объекта равен нулю.

а также у нас есть это:

x.Equals (y) возвращает то же значение, что и y.equals (х).

Нет проблем, пока здесь. Это очень похоже на Java. Но C # также предоставляет структуру System.Nullable для необнуляемых типов. Насколько я знаю, структура это объект. Он наследует метод Object.Equals.

Если у меня есть такая структура:

struct Car
    {
        public string Make;
        public string Model;
        public uint Year;

        public Car(string make, string model, uint year)
        {
            Make = make;
            Model = model;
            Year = year;
        }
    }

И создайте четыре экземпляра:

Car car1 = new Car("make", "model", 2009);
Car car2 = new Car("make", "model", 2009);
Car car3 = new Car("make", "model", 2008);

car1.Equals(car2); // will return true
car1.Equals(car3); // will return false;

И, насколько я знаю, мы не можем установить структуру в нулевое значение. Но System.Nullable - это структура, и мы можем скомпилировать ее без ошибок:

int? i = null;

(Я надеюсь, что кто-то также может объяснить это. Это структура или что-то еще?)

Мой настоящий вопрос:

i.Equals(null); // returns true!

(Обычно x.Equals (y) = y.Equals (x) Конечно, null. Equals (i) здесь недопустим ...)

Очевидно, что метод Object.Equals здесь переопределен. Может быть, это задокументировано, и это указано. Но правильно ли это / хорошо? Если да, в чем разница между == и методом Equals для значений Nullable?

Ответы [ 2 ]

9 голосов
/ 09 октября 2009

Я думаю, что ваше замешательство коренится в следующей строке

i? = null;

Это фактически не создает переменную с нулевым значением. Это по сути синтетический сахар для следующего

Nullable<int> i = new Nullable<int>();

Полученное свойство HasValue для i будет иметь значение false. Это не NULL, а тип значения с пустыми значениями. Или просто пустой обнуляемый. ИМХО, лучший способ думать об этом состоит в том, что нуль может быть преобразован в пустой Nullable<T> для любого заданного значения T.

Зная, что это делает строку i.Equals (null) немного легче для понимания. Это синтетический сахар для следующих

Nullable<int> i = new Nullable<int>();
i.Equals(null);

Тип Nullable<T> только переопределяет Equals (объект). Реализация этого метода, тем не менее, считает пустое значение равным пустому значению. Так что ведёт себя правильно.

2 голосов
/ 09 октября 2009

Чтобы ответить на ваш дополнительный вопрос, Nullable - это структура с ограничением T: Struct. Итак, хотя int? я = ноль; имеет значение null, i является экземпляром структуры Nullable.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...