snippetcsharpCritical
How do I check if a type is a subtype OR the type of an object?
Viewed 0 times
objecthowcheckthesubtypetype
Problem
To check if a type is a subclass of another type in C#, it's easy:
However, this will fail:
Is there any way to check whether a type is either a subclass OR of the base class itself, without using an
typeof (SubClass).IsSubclassOf(typeof (BaseClass)); // returns trueHowever, this will fail:
typeof (BaseClass).IsSubclassOf(typeof (BaseClass)); // returns falseIs there any way to check whether a type is either a subclass OR of the base class itself, without using an
OR operator or using an extension method?Solution
Apparently, no.
Here's the options:
Type.IsSubclassOf
As you've already found out, this will not work if the two types are the same, here's a sample LINQPad program that demonstrates:
Output:
Which indicates that
Type.IsAssignableFrom
Now, this will answer your particular question, but it will also give you false positives. As Eric Lippert has pointed out in the comments, while the method will indeed return
Here you get the following output:
The last
So
The "problem" with
In other words, this won't compile:
nor will this:
nor will this:
Conclusion
While the above methods might fit your needs, the only correct answer to your question (as I see it) is that you will need an extra check:
which of course makes more sense in a method:
Here's the options:
- Use Type.IsSubclassOf
- Use Type.IsAssignableFrom
isandas
Type.IsSubclassOf
As you've already found out, this will not work if the two types are the same, here's a sample LINQPad program that demonstrates:
void Main()
{
typeof(Derived).IsSubclassOf(typeof(Base)).Dump();
typeof(Base).IsSubclassOf(typeof(Base)).Dump();
}
public class Base { }
public class Derived : Base { }Output:
True
FalseWhich indicates that
Derived is a subclass of Base, but that Baseis (obviously) not a subclass of itself.Type.IsAssignableFrom
Now, this will answer your particular question, but it will also give you false positives. As Eric Lippert has pointed out in the comments, while the method will indeed return
True for the two above questions, it will also return True for these, which you probably don't want:void Main()
{
typeof(Base).IsAssignableFrom(typeof(Derived)).Dump();
typeof(Base).IsAssignableFrom(typeof(Base)).Dump();
typeof(int[]).IsAssignableFrom(typeof(uint[])).Dump();
}
public class Base { }
public class Derived : Base { }Here you get the following output:
True
True
TrueThe last
True there would indicate, if the method only answered the question asked, that uint[] inherits from int[] or that they're the same type, which clearly is not the case.So
IsAssignableFrom is not entirely correct either.is and asThe "problem" with
is and as in the context of your question is that they will require you to operate on the objects and write one of the types directly in code, and not work with Type objects.In other words, this won't compile:
SubClass is BaseClass
^--+---^
|
+-- need object reference herenor will this:
typeof(SubClass) is typeof(BaseClass)
^-------+-------^
|
+-- need type name here, not Type objectnor will this:
typeof(SubClass) is BaseClass
^------+-------^
|
+-- this returns a Type object, And "System.Type" does not
inherit from BaseClassConclusion
While the above methods might fit your needs, the only correct answer to your question (as I see it) is that you will need an extra check:
typeof(Derived).IsSubclassOf(typeof(Base)) || typeof(Derived) == typeof(Base);which of course makes more sense in a method:
public bool IsSameOrSubclass(Type potentialBase, Type potentialDescendant)
{
return potentialDescendant.IsSubclassOf(potentialBase)
|| potentialDescendant == potentialBase;
}Code Snippets
void Main()
{
typeof(Derived).IsSubclassOf(typeof(Base)).Dump();
typeof(Base).IsSubclassOf(typeof(Base)).Dump();
}
public class Base { }
public class Derived : Base { }void Main()
{
typeof(Base).IsAssignableFrom(typeof(Derived)).Dump();
typeof(Base).IsAssignableFrom(typeof(Base)).Dump();
typeof(int[]).IsAssignableFrom(typeof(uint[])).Dump();
}
public class Base { }
public class Derived : Base { }True
True
TrueSubClass is BaseClass
^--+---^
|
+-- need object reference heretypeof(SubClass) is typeof(BaseClass)
^-------+-------^
|
+-- need type name here, not Type objectContext
Stack Overflow Q#2742276, score: 631
Revisions (0)
No revisions yet.