Check if object of base class came from subclass

98 Views Asked by At

I have a base class and a bunch of subclasses of it.

I have an object of base class and I know that it was an instance of one of the subclasses before, but it was casted to the base class.

I want to know how to discover which subclass it was before. More specifically:

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

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

How can I write this if correctly? Is it even possible?

3

There are 3 best solutions below

3
Enigmativity On BEST ANSWER

Using is DOES NOT WORK.

It does not "discover which subclass it was before", just that it can be cast to the given type.

Take these class definitions:

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

I can write this code and it gets it WRONG:

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

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

It tells me that bc is IntermediateClass, but it's not. It's a BaseClass.

The only way to do it is a direct equality comparison.

This works:

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

is operator

The is operator checks if the result of an expression is compatible with a given type.

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

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

update

this only check if bc is castable to Subclass(subclass is one of the parents types). Although I still see that the word is-a still valid.

But as mentioned by @Enigmativity to be more accurate if you ask about the creating source type

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

elaborate more

I see you have a list of base classes, and you want to select an object by its type ... suppose the following classes

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 { }

and you have list of Organism

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

examin the following queries

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)]
1
Hr.Panahi On

You can use is operator instead of 'was' in your if statement:

It checks wether an object is compatible with a given type and returns true if the object is compatible; otherwise, returns false.

Additionally you have to write Console.WriteLine() instead of 'print'.