2009-10-08 3 views
2

Я говорю о языке C# здесь.Is Nullable <T>. Реализация метода Equals Wrong?

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

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

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

x.Equals (пустая ссылка (Nothing в Visual Basic )) возвращает ложь.

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

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

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

x.Equals (у) возвращает то же значение, как 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.equals (х) Конечно null.Equals (I) не действует здесь ...)

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

ответ

9

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

i? = null; 

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

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

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

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

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

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

+0

Но, что бы он ни делал в фоновом режиме, мы вызываем i.Equals (null), и он возвращает true, когда i равно null. Он должен возвращать false для любого другого объекта. – JCasso

+0

@jcasso, Nullable в общем ... странны и часто ведут себя неожиданными способами. Часть путаницы заключается в том, что я никогда не могу быть нулевым, потому что это фактически тип значения. Лучше думать об этом как о пустом значении. – JaredPar

+0

По крайней мере, вы признали, что это странно :) Я думал, что я единственный. – JCasso

2

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

+0

Структура может принимать нулевое значение? Можете ли вы определить Car car4 = null; ? – JCasso

+1

Структура не может иметь значение «null» для CLR. В C#, когда вы пишете 'int? x = null', вы на самом деле пишете 'int? x = new int?() '. Там вообще нет никакого «нулевого». –

+1

№. но когда вы делаете int? i = << некоторая юридическая ценность >>, CLR помещает это юридическое значение в значение value i. Кроме того, только FYI, Nullable переопределяет метод Equals –

Смежные вопросы