0

Suppose I have a class Animal, and several sub-classes, Dog, Cat, Bird, etc.

Now I have a Person, who has an Animal. She wants to see if the pet store has an animal of the same type.

So I have:

Animal sampleAnimal;
List<Animal> listOfAnimals;  // in our hypothetical pet store

When I try to do this (in C# 3.5):

Type typeWeWant = sampleAnimal.GetType();
foreach (var x in listOfAnimals) {
  if (x is typeWeWant) { // error here
     return true;
  }
}

I get the error "typeWeWant is a variable but is used like a type."

Okay. How do I do this?

Keep in mind, our Person might have a CalicoCat, which is a subclass of Cat, and it should match against Cat. So using GetType.ToString() won't work. (Pets are not exactly what's going on in my case - if the code as written worked, I would be fine. I don't need to test both ways.)

I apologise if this has been asked anywhere already, but all I could find were questions regarding generics, which is not quite the case here.

EDIT: Thank you SO much for both the answers and the "duplicate" link! These are exactly what I needed and could not find!

Peter Kay
  • 133
  • 7

4 Answers4

4

You can use Type.IsAssignableFrom as follows:

if (typeWeWant.IsAssignableFrom(x.GetType()))
    return true;

This covers both the subclass and type equality cases.

György Kőszeg
  • 17,093
  • 6
  • 37
  • 65
2

In the if condition use either

if (x.GetType() == typeWeWant)

or, if you need to find all type of cats, including subclasses of cats

if (typeWeWant.IsSubclassOf(x.GetType())
if (x.GetType().IsSubclassOf(typeWeWant)
Max
  • 751
  • 6
  • 10
  • 1
    you can't use IsSubclassOf like that. IsSubclassOf is member of Type - so you can use `x.GetType().IsSubclassOf(typeWeWant)` – Ivan Salo Feb 26 '19 at 20:46
  • @IvanSalo, thanks, forgot it. Edited the answer. – Max Feb 26 '19 at 20:48
  • 2
    `This method also returns false if c and the current Type are equal.` from https://learn.microsoft.com/en-us/dotnet/api/system.type.issubclassof?view=netframework-4.7.2 (which I doubt is what you want). I think you might be better with `IsAssignableFrom`. – mjwills Feb 27 '19 at 03:56
1

You can do something like this:

Type typeWeWant = sampleAnimal.GetType();
foreach (var x in listOfAnimals) {
  // with check only by type of typeWeWant
  if (x.GetType() == typeWeWant) {
     return true;
  }
  // depends on your needs you can use one of following
  // will check if typeWeWant is subclass of x
  if (typeWeWant.IsSubclassOf(x.GetType()) {
     return true;
  }
  // will check if x is subclass of typeWeWant
  if (x.GetType().IsSubclassOf(typeWeWant)) {
     return true;
  }
}
Ivan Salo
  • 811
  • 1
  • 9
  • 25
  • 1
    Am... Correct me if I'm wrong, but it will compile, but won't work, because `typeof(typeWeWant)` is `Type`, not an `Animal` or its children. – Max Feb 26 '19 at 20:39
  • Would it perhaps be worth explaining what this check is not **exactly** the same as an `is` check, and how their results might differ? – mjwills Feb 26 '19 at 20:42
  • to check subclass please use `typeWeWant.IsSubclassOf(x.GetType())` or `x.GetType().IsSubclassOf(typeWeWant)` depends on your needs – Ivan Salo Feb 26 '19 at 20:48
-1

Had a play around and this is what I got working:

 Type typeWeWant = sampleAnimal.GetType();
 foreach (var x in listOfAnimals)
 {
     if (typeWeWant.IsInstanceOfType(x))
     {
         return true;
     }
 }

This also works:

Type typeWeWant = sampleAnimal.GetType();
foreach (var x in listOfAnimals)
{
    if (typeWeWant.IsSubclassOf(x.GetType()))
    {
        return true;
    }
}
HenryMigo
  • 164
  • 1
  • 7