Проверьте, произошел ли объект базового класса из подкласса

У меня есть базовый класс и несколько его подклассов.

У меня есть объект базового класса, и я знаю, что раньше он был экземпляром одного из подклассов, но был приведен к базовому классу.

Я хочу знать, как узнать, какой подкласс был раньше. Более конкретно:

SubClass sc = new SubClass();
BaseClass bc = sc;

if (bs was SubClass) print("bc was SubClass");

Как мне написать это if правильно? Возможно ли это вообще?

Принятый вами ответ подходит не для всех случаев.

Enigmativity 18.03.2024 01:47
Стоит ли изучать 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 называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
1
103
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

оператор

Оператор is проверяет, совместим ли результат выражения с заданным типом.

SubClass sc = new SubClass();
BaseClass bc = sc;

if (bc is SubClass)
    Console.WriteLine("bc is a Subclass");

обновлять

это только проверка, можно ли bc привести к Subclass (подкласс является одним из родительских типов). Хотя я все еще вижу, что слово -а все еще актуально.

Но, как упоминалось в @Enigmativity, если вы спросите о создании типа источника, будет точнее.

if (bc.GetType() == typeof(SubClass)) 
    Console.WriteLine("bc created from Subclass"); 

подробнее

Я вижу, у вас есть список базовых классов, и вы хотите выбрать объект по его типу... предположим, что следующие классы

public class Organism { public string? Name; }
public class Person : Organism { }
public class Animal : Organism { }
public class Cat : Animal { }
public class Dog : Animal { }
public class Horse : Animal { }

и у вас есть список Organism

List<Organism> organisms = [
     new Person{Name = "ibram"},
     new Cat(){Name  = "memo"},
     new Horse{Name = "flash"}
    ];

изучите следующие запросы

organisms.Where(organism => organism is Animal); // will return [Cat(memo), Horse(flash)]
organisms.Where(organism => organism.GetType() == typeof(Animal)); // return empty [] there is no object in list created from animal
organisms.Where(organism => organism.GetType() == typeof(Cat)); // will return [Cat(memo)] 
organisms.Where(organism => organism is Person); // will return [Person(ibram)]

Это не «обнаруживает, какой подкласс был раньше», просто его можно привести к заданному типу.

Enigmativity 18.03.2024 01:40

@Enigmativity спасибо за сотрудничество для большей ясности... вы совершенно правы

Ibram Reda 18.03.2024 03:59

Вы можете использовать оператор is вместо «was» в операторе if:

Он проверяет, совместим ли объект с заданным типом, и возвращает true, если объект совместим; в противном случае возвращает false.

Кроме того, вместо «печатать» необходимо написать Console.WriteLine().

Это не «обнаруживает, какой подкласс был раньше», просто его можно привести к заданному типу.

Enigmativity 18.03.2024 01:40
Ответ принят как подходящий

Использование is НЕ РАБОТАЕТ.

Он не «обнаруживает, каким подклассом он был раньше», просто его можно привести к заданному типу.

Возьмите эти определения классов:

public class BaseClass { }
public class IntermediateClass : BaseClass { }
public class SubClass : IntermediateClass { }

Я могу написать этот код, и он будет НЕПРАВИЛЬНЫМ:

SubClass sc = new SubClass();
BaseClass bc = sc;

if (bc is IntermediateClass)
{
    Console.WriteLine("bc is IntermediateClass");
}

Мне это говорит bc is IntermediateClass, но это не так. Это BaseClass.

Единственный способ сделать это — прямое сравнение на равенство.

Это работает:

if (bc.GetType() == typeof(SubClass))
{
    Console.WriteLine("bc is Subclass");
}

@Daniel, если он возвращает значение null, то это означает, что в списке нет объекта, экземпляр которого создается из типа T

Ibram Reda 18.03.2024 23:40

@Daniel - Какой тип T? Если это универсальный тип, вы явно указываете его при вызове? Вам нужно будет показать мне полный код, который вы пытаетесь использовать. Все, что я публикую, было проверено перед публикацией. Я знаю, что мой код работает.

Enigmativity 19.03.2024 01:22

@Daniel, пожалуйста, не удаляй комментарии. Они обеспечивают контекст для комментариев.

Enigmativity 19.03.2024 02:03

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