简体   繁体   中英

Consider all inherited classes when using typeof

I have several classes (one of which is called Pet ) that extend the class Animal . If I have a generic method, can I use typeof to compare with the base class?

if (typeof(T) == typeof(Animal))
{
    return ((Animal)pet).Color;
}

What's currently happening in my code is that this clause is getting skipped entirely. This isn't desired in this particular example, since Pet inherits from Animal .

Instead of using typeof(T) == typeof(Animal) , do:

var animal = pet as Animal;
if(animal != null)
  return animal.Color;

This saves you an extra type check.

Note about as and is

as can only be used for reference types. If you try to cast using as and it fails... it will return null . If you JUST want to check to see if a value is of a certain type, use is . It returns a boolean .

Where keyword

But, lets also look at what you can do with generics!

public void Foo<T>(T pet)
  where T : Animal
{
}

Notice the where keyword. This will force at compile time that T is of type Animal . This way... you never even have to verify!

Which means your function could look like:

public void Foo<T>(T pet)
  where T : Animal
{
  return pet.Color;
}

Cleaner and faster!

While I would personally go the route of the C# as operator for most of these situations (see Andrew's answer), you can also use Type.IsAssignableFrom , depending on your needs:

if (typeof(Animal).IsAssignableFrom(typeof(T)))
{
    return ((Animal)pet).Color;
}

On a side note, I generally prefer Type.IsAssignableFrom over Type.IsSubclassOf because IsAssignableFrom also works with interfaces.

Oh, you could also use is :

if (pet is Animal)
{
    return ((Animal)pet).Color;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM