Переменная «a» имеет ссылочный тип, а «A» — это пользовательский класс. Если значение «a» равно нулю, почему «a is A» дает значение true?

Обновлено: этот код был написан в 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.

null — возможное значение для любого ссылочного типа. Вы можете присвоить его любой переменной ссылочного типа. С другой стороны, если бы вы использовали if (mirr is BoxExit x), вы бы использовали сопоставление с образцом, которое проверяет, что mirr является фактическим ненулевым значением BoxExit.
Panagiotis Kanavos 21.03.2024 14:41
Я не могу это воспроизвести ... Я думаю, что это может выглядеть так в отладчике, если информация в pdb отличается от кода в IDE
Selvin 21.03.2024 14:46
dotnetfiddle.net/Xzi1mv
gunr2171 21.03.2024 14:49

@Selvin Это действительно странно! Я использую Microsoft Visual Studio 2022, и каждый раз, когда я отлаживаю, mirr — это BoxExit, который всегда оценивается как true. Я не уверен, почему на разных платформах может быть разница.

vainquit 21.03.2024 15:04

@Heinzi Вы правы! Это было отменено! Я использую Unity, и операция == была переопределена движком!

vainquit 21.03.2024 15:22

Можете ли вы сказать, что делает Unity с помощью своего переопределенного оператора ==?

Orion 21.03.2024 15:38

@vainquit: Ах, отлично. Я расширил свой комментарий до ответа, чтобы вы могли пометить вопрос как отвеченный, если захотите. (Если быть точным, я восстановил ответ, который уже написал, прежде чем решил, что комментарий будет более подходящим для догадок.)

Heinzi 21.03.2024 16:06
Стоит ли изучать 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
8
81
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Мы ничего не знаем о типе 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;
}

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