Почему integer == null
действительное булевское выражение в C#, если integer
(переменная типа int
) не допускает ошибки? (Я не против этого, на самом деле мне это нравится, но я не знаю, что это было возможно)Почему integer == null является допустимым булевым выражением в C#?
ответ
Хотя int
сами ненулевой, есть неявное преобразование в int?
, который является обнуляемыми.
В этот момент, если структура объявляет оператор ==
с тем же типом с обеих сторон, то это также отменено для работы с нулевыми типами.
Так что это не компилируется:
public struct Foo {}
class Test
{
static void Main()
{
Foo x = new Foo();
if (x == null)
{
...
}
}
}
... но если вы даете Foo
некоторые операторы, это делает компилировать и без предупреждения:
public struct Foo
{
public static bool operator ==(Foo x, Foo y) { return true; }
public static bool operator !=(Foo x, Foo y) { return false; }
public override bool Equals(object x) { return false; }
public override int GetHashCode() { return 0; }
}
Оператор вызова не входит в скомпилированный код, потому что компилятор знает, что RHS имеет значение NULL.
Так код выше форм (где Foo
может быть заменены на любом не обнуляемом struct
) имеет один из трех результатов с # 5 компилятором MS C:
- Внимание CS0472 (например, с
int
) - Ошибка CS0019 (пользовательские типы, которые не перегружают
==
) - Clean компиляции (пользовательские типы, которые перегружают
==
, в том числе иGuid
DateTime
)
Непонятно, почему компилятор рассматривает некоторые «известные» типы по-разному для обычных структур. EDIT: Как заметил Эрик в комментариях, это известная ошибка в компиляторе C#, который, как мы надеемся, зафиксирован в Roslyn.
Bah, лучший ответ чем мой ... –
Черт, это странно! Может быть, структурирование является исключением? –
@ guillegr123: Я все еще пытаюсь это выработать ... –
Как Эд упоминает есть предупреждение, но предупреждение намекает на причину: int
может быть автоматически отливают в int?
и null
является допустимым значением для переменной типа int?
.
Вы получаете предупреждение, что-то вроде строк «выражение всегда ложно». Что касается того, почему это * разрешено *, то есть не приводит к ошибке времени компиляции ... Я полагаю, что по той же причине это разрешено; 'while (true)' –
Компилятор C# во время компиляции оптимизирует это значение false при компиляции в режиме деблокирования ('ldc.i4.0' заканчивается тем, что находится в IL). – vcsjones
Возможный дубликат [C# okay с сопоставлением типов значений с нулевым] (http://stackoverflow.com/questions/1972262/c-sharp-okay-with-comparing-value-types-to-null) –