В C # 7 мы можем использовать
if (x is null) return;
вместо того
if (x == null) return;
Есть ли преимущества использования нового способа (прежний пример) по сравнению со старым?
Семантика отличается?
Это просто вопрос вкуса? Если нет, когда я должен использовать один поверх другого?
Ссылка: Что нового в C # 7.0 .
Ответы:
Обновление: компилятор Roslyn был обновлен, чтобы сделать поведение двух операторов одинаковым, когда нет перегруженного оператора равенства . Пожалуйста, смотрите код в результатах текущего компилятора (
M1
иM2
в коде), который показывает, что происходит, когда нет перегруженного компаратора равенства. Они оба теперь ведут себя лучше==
. Если имеется перегруженный компаратор равенства, код все равно будет другим .Смотрите более ранние версии компилятора Roslyn ниже анализ.
Потому
null
что нет разницы с тем, к чему мы привыкли в C # 6. Однако, вещи становятся интересными, когда вы переходитеnull
на другую константу.Возьмите это к примеру:
Тест дает
a
. Если вы сравните это сo == (object)1
тем, что написали бы, как обычно, это будет чертовски важно.is
принимает во внимание тип на другой стороне сравнения. Это круто!Я думаю, что паттерн «
== null
противis null
константы» просто очень знаком «случайно», где синтаксисis
оператора и оператора равенства дают один и тот же результат.Как прокомментировал свик ,
is null
звонкиSystem.Object::Equals(object, object)
куда==
звонятceq
.IL для
is
:IL для
==
:Поскольку мы говорим о том
null
, что нет никакой разницы, поскольку это имеет значение только в случаях . Это может измениться, если вы перегружаете оператор равенства.источник
is
вызовыobject.Equals(x, null)
, а==
компилируется какceq
. Но результат должен быть таким же, как вы сказали.==
это перегружаемый оператор. Вы можете иметь любое поведение, которое вы хотите с ним. Например, эта странная реализация не==
скажет вам, является ли ваш экземпляр действительно нулевым.is null
с другой стороны, всегда будет возвращать true для истинных нулевых ссылок :) Кроме того, если у вас естьReferenceEquals
код, лампочки VS 2017 предложат изменить наis null
, а не== null
(правильно).is
больше нет накладных расходов на вызов функции при использовании для проверки на ноль. Для доказательства смотрите ссылку, размещенную @svick в комментариях.Перегруженный оператор равенства
На самом деле существует разница в семантике между двумя сравнениями, когда вы сравниваете
null
с типом, который перегружает==
оператор.foo is null
будет использовать прямое сравнение ссылок для определения результата, тогда какfoo == null
, конечно, запустит перегруженный==
оператор, если он существует.В этом примере я ввел «ошибку» в перегруженном
==
операторе, заставляя его всегда генерировать исключение, если второй аргументnull
:Код IL для
foo is null
использованияceq
инструкции для прямого сравнения ссылок:В IL-коде
foo == null
используется вызов перегруженного оператора:Таким образом, разница заключается в том, что при использовании
==
вы рискуете запустить пользовательский код (который может иметь непредвиденное поведение или проблемы с производительностью).Ограничение на дженерики
Использование
is null
конструкции ограничивает тип ссылочным типом. Компилятор обеспечивает это, что означает, что вы не можете использоватьis null
тип значения. Если у вас есть универсальный метод, вы не сможете его использовать,is null
если универсальный тип не ограничен ссылочным типом.Спасибо Дэвиду Аугусто Вилле за указание на это.
источник