Reputation: 515
I have a generic abstract class which I derive from:
abstract class SuperClass<T>
where T : SuperDataClass
abstract class SuperDataClass
The data type is limited to SuperDataClass, so every concrete data type must inherit from SuperDataClass. In the end I have pairs of SuperClass and SuperDataClass inheriters, e.g.:
class DataClassA : SuperDataClass
class ClassA : SuperClass<DataClassA>
class DataClassB : SuperDataClass
class ClassB : SuperClass<DataClassB>
How can I check if an object, e.g. ClassA inherits from SuperClass without knowing the possible data type?
I tried the following, which does not work:
if (testObject.GetType().IsAssignableFrom(typeof(SuperClass<SuperDataClass>))) {
Console.WriteLine("The test object inherits from SuperClass");
}
So how does the if-statement needs to look like?
Upvotes: 5
Views: 4511
Reputation: 17603
Use the IsSubclassOf function in conjunction with the generic type:
if (@object.GetType().IsGenericType &&
@object.GetType().GetGenericTypeDefinition().IsSubclassOf(typeof(SuperClass<>))) {
Console.WriteLine("The object inherits from SuperClass");
}
Where @object
is the type you want to check (i copied the naming from your question, but object is no good name because it's the superclass of all classes).
If you want to check the generic type param as well, use
if (@object.GetType().IsGenericType &&
@object.GetType().GenericTypeArguments[0].IsSubclassOf(typeof(SuperDataClass)) &&
@object.GetType().IsSubclassOf(typeof(Superclass<>)))
EDIT: your last comment - non generic type deriving from generic type:
if (@object.GetType().IsSubclassOf(typeof(Superclass<>)))
Upvotes: 1
Reputation: 40576
Apparently all obvious solutions (IsSubclassOf
, IsAssignableFrom
, is
, as
) do not work in this case. So I tried to force things a bit and came up with this way of testing if a class is SuperClass<Something>
:
private bool IsSuperClassOfSomeKindOfSuperDataClass(Type type)
{
if (!type.IsGenericType)
return false;
var gtd = type.GetGenericTypeDefinition();
if (gtd != typeof(SuperClass<>))
return false;
var genericParameter = type.GetGenericArguments().First();
return genericParameter.IsSubclassOf(typeof(SuperDataClass));
}
Of course, this tests if a class is SuperClass<Something>
, not if it inherits from SuperClass<Something>
, so the next obvious step would be to write a function that tests all inheritance hierarchy for a suitable class:
private bool InheritsFromSuperClassOfSomeKindOfSuperDataClass(Type type)
{
while (type != typeof(Object))
{
if (IsSuperClassOfSomeKindOfSuperDataClass(type))
return true;
type = type.BaseType;
}
return false;
}
With these functions in place, the test you're looking for is:
if (InheritsFromSuperClassOfSomeKindOfSuperDataClass(@object.GetType()))
// do stuff...
Upvotes: 1
Reputation: 111940
Recursively
Type type2 = type; // type is your type, like typeof(ClassA)
while (type2 != null)
{
if (type2.IsGenericType &&
type2.GetGenericTypeDefinition() == typeof(SuperClass<>))
{
// found
}
type2 = type2.BaseType;
}
Note that this won't work if you are looking for an interface!
Upvotes: 1
Reputation: 23831
Here you should have some clue as to what the expected type is. So in this case I would use the Type.IsSubclassOf Method.
An example of it's use is
Class1 myClass = new Class1();
DerivedC1 myDClass = new DerivedC1();
Type myClassType = myClass.GetType();
Type myDClassType = myDClass.GetType();
// Returns true.
bool isSubClass = myDClassType.IsSubclassOf(myClassType));
I hope this helps.
Upvotes: 0