Различные Способы Проверки на Null в C#
В .NET существует несколько способов проверки на null. Но не все они равнозначны. Рассмотрим различные способы проверки:
object obj = ...;Есть 3 основных способа:
// Основные проверки
obj == null;
object.Equals(obj, null);
object.ReferenceEquals(obj, null);
// Аналогичны ReferenceEquals(obj, null)
obj is null;
(object)obj == null;
// Аналогичны !ReferenceEquals(obj, null)
obj is not object;
obj is not {};
// Не работает, выдаёт NullReferenceException
obj.Equals(null);
1. object.ReferenceEquals(obj, null)
ReferenceEquals возвращает true, если экземпляры объекта являются одним и тем же экземпляром. В этом случае он возвращает true, если obj имеет значение null.2. object.Equals(obj, null)
Equals аналогичен
ReferenceEquals, когда один аргумент имеет значение null. Однако логика этого метода сложнее, чем ReferenceEquals, и немного медленнее, поскольку вызов метода не всегда встраивается.3. obj == null
Оператор
== аналогичен ReferenceEquals, если вы не определяете оператор равенства для класса. Если оператор определён, компилятор использует его вместо оператора по умолчанию. В этом случае логика сравнения настраивается, и она может и не учитывать проверку на null. Вы можете заставить компилятор использовать оператор ==, определённый для object, путём явного преобразования объекта к object.Заметьте, что is null не работает со структурами, кроме обнуляемых:
MyStruct a = default;Заметьте, что хотя сопоставления с образцом
// Ошибка компиляции
_ = a is null;
// Работает, только если MyStruct
// определяет оператор ==
_= a == null;
Span<char> span = default;
// Ошибка компиляции
_ = span is null;
// Работает, т.к. Span определяет оператор ==
_ = span == null;
int? b = null;
// Аналогично !b.HasValue
_ = b is null;
is not null, is object и is {} аналогичны одной и той же проверке на null (см. выше), использование их вместе с объявлением переменной различается:// Ошибка компиляцииИсточник: https://www.meziantou.net/null-check-in-csharp.htm
if (obj is not null x) { … }
// OK, х – типа object
if (obj is object x) { … }
// OK, x – того же типа, что и obj
if (obj is {} x) { … }