Не равно нулю Vs != null (Unity C#)

Единственное отличие (помимо синтаксиса) заключается в том, что компилятор гарантирует, что при использовании is not null вместо != null (или is null вместо == null) не будет вызываться ни один перегруженный пользователем оператор.

Согласно этим объяснениям, между этими двумя понятиями не должно быть никакой разницы.

Но когда я использую движок Unity с данными Json Я вижу функциональное отличие: Is Not null не распознает Джейсона как пустое, но распознает те же данные как пустые, когда я проверяю их с помощью !=

В чем причина этого?

Может что-то не так, извините (используется переводчик)

Я ожидал, что при обоих условиях будет обнаружено нулевое значение.

быть пустым и быть нулевым - это две разные вещи

Raildex 18.08.2024 12:14

Разница лишь в том... и... разницы быть не должно..., Вам не кажется, что эти два предложения противоречат друг другу?

shingo 18.08.2024 12:36
Raildex - Означает ли это, что он проверяет только значение is not null? Что, если этот человек не Json?
Rez_Ait 18.08.2024 12:53
Видимо Unity делает "странные вещи" с нулевыми проверками
Hans Kesting 18.08.2024 13:45

@hans-keffing Точно, C# делает то же самое в консоли, поэтому обходного пути нет.

Rez_Ait 18.08.2024 14:31
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
5
51
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я ожидал, что при обоих условиях будет обнаружено нулевое значение.

Да, оба оператора обнаруживают истинные нулевые значения. Однако Unity немного особенная. Unity — это движок C++, и когда дело доходит до управления памятью, возникают некоторые серьезные проблемы. В C# вы не можете уничтожить какой-либо объект вручную, поскольку это полностью находится в руках сборщика мусора. Ссылки на объекты не могут внезапно стать нулевыми в C#.

Поскольку собственные (C++) объекты Unity могут быть уничтожены в любой момент, это создает проблему на уровне сценариев C#. Ссылка на GameObject или другой компонент не может волшебным образом стать нулевой. Итак, Unity использует трюк. Они перегрузили оператор == и метод Equals, и при сравнении мертвых объектов с нулевым значением они вернут true. Это называется поддельным нулевым объектом. Это по-прежнему допустимый объект C#, но его больше нельзя использовать, поскольку фактический собственный объект был уничтожен. Большинство встроенных компонентов и классов в Unity — это просто классы-оболочки C#, за кулисами которых находится собственный объект. (Каждый класс, производный от UnityEngine.Object)

Это означает, что вы не можете использовать is null или любой из операторов объединения значений NULL для переменных с типом, производным от UnityEngine.Object. Когда эти ссылки действительно равны нулю, это будет работать. Однако в большинстве случаев вы столкнетесь с поддельным нулевым объектом, и проверка is null не увидит его как нулевой, поскольку это все еще экземпляр.

Около 10 лет назад в блоге была запись о перегрузке оператора == . Вот справочный источник Unity и пользовательский оператор ==. Как вы можете видеть, он на самом деле вызывает CompareBaseObjects, и когда объект мертв, он «подделывает», что он равен нулю.

Многие говорят, что это было плохое решение, однако это решение было принято, когда единственным оператором, который выполнял прямую проверку нуля, был ??. В последние годы в C# появилось множество операторов, которые также обходят перегрузку операторов, поэтому эта проблема становится растущей. Однако избавление от перегрузки означало бы, что вам всегда придется выполнять дополнительную IsAlive проверку вручную, поскольку вы не сможете избавиться от фундаментального конфликта между миром C++ и C#.

Это было интересно, я не знал, что это так работает, поэтому мне следует избегать использования новых операторов C#. Большое спасибо за предоставленные вами ссылки ♥♥♥

Rez_Ait 19.08.2024 10:05

Другие вопросы по теме