Обновлено: этот код был написан в Unity, и Unity переопределил оператор «==» и даже «ноль». Это фон.
Текстовая версия:
var mirr = RecursedManager.instance.currentEntrance;
if (mirr == null)
{
if (mirr is BoxExit)
{
var a = 1;// Even without debug mode, this line will be executed, if I use "print(1)" instead.
}
}
Изображение выше — это снимок экрана, сделанный во время отладки в C#. Он показывает, что выполнение достигает строки «var a = 1». Поскольку он достиг этой линии, это указывает на то, что оба условия «mirr == null» и «mirr is BoxExit» выполняются одновременно. Я не понимаю, почему нулевое значение можно рассматривать как подкласс класса BoxExit.
Я слышал объяснение, что «переменные содержат информацию о типе, а null — нет». Этот вывод также был моей первой реакцией. Однако я привел простой пример, который, кажется, противоречит этому рассуждению. Например:
string aa = null;
bool b = aa is string;
print(b); // The output of b is false
Наконец, некоторая дополнительная информация (относительно определения currentEntrance, не уверена, нужна ли она):
public IEntrance currentEntrance { get => _instance._currentEntrance; set => _instance._currentEntrance = value; }
private IEntrance _currentEntrance;
Где «BoxExit» — это определенный мной пользовательский класс, унаследованный от класса Unity «MonoBehaviour». Кроме того, класс BoxExit реализует интерфейс IEntrance.
Ваш класс BoxExit переопределяет оператор ==? Это могло бы объяснить такое поведение. В противном случае предоставьте минимально воспроизводимый пример.
@Selvin Это действительно странно! Я использую Microsoft Visual Studio 2022, и каждый раз, когда я отлаживаю, mirr — это BoxExit, который всегда оценивается как true. Я не уверен, почему на разных платформах может быть разница.
@Heinzi Вы правы! Это было отменено! Я использую Unity, и операция == была переопределена движком!
Можете ли вы сказать, что делает Unity с помощью своего переопределенного оператора ==?
@vainquit: Ах, отлично. Я расширил свой комментарий до ответа, чтобы вы могли пометить вопрос как отвеченный, если захотите. (Если быть точным, я восстановил ответ, который уже написал, прежде чем решил, что комментарий будет более подходящим для догадок.)





Мы ничего не знаем о типе mirr, поэтому можем только догадываться, но классы C# определенно могут переопределить оператор ==.
Следующий пример (рабочий пример) выведет True дважды:
using System;
S s = new S();
Console.WriteLine(s == null);
Console.WriteLine(s is S);
class S
{
public static bool operator==(S s1, S s2) => true;
public static bool operator!=(S s1, S s2) => false;
}
null— возможное значение для любого ссылочного типа. Вы можете присвоить его любой переменной ссылочного типа. С другой стороны, если бы вы использовалиif (mirr is BoxExit x), вы бы использовали сопоставление с образцом, которое проверяет, чтоmirrявляется фактическим ненулевым значениемBoxExit.