Supose i have:
class MyBase<T1, T2>{}
class MyConcreteBase<T2> : MyBase<ConcreteType1, T2>{}
class MyConcrete1 : MyConcreteBase<ConcreteType2>{}
class MyConcrete2 : MyBase<ConcreteType1, ConcreteType2>{}
How do i get types of T1
and T2
if i have instance of MyConcrete1
or MyConcrete2
or MyConcreteBase
or any other instance of type derived from MyBase<T1, T2>
The way i do it now is i'm "getting up" by inheritance chain using .GetType().BaseType
while BaseType.Name.StartsWith("MyBase")
and then using .GetGenericArguments()
It is working, but i'm not satisfied with it, especially .StartsWith("MyBase")
part.
Anyone have other suggestions?
An attribute cannot inherit from a generic class, nor can a generic class inherit from an attribute.
The generic argument list is a comma-separated list of type arguments. A type argument is the name of an actual concrete type that replaces a corresponding type parameter in the generic parameter clause of a generic type. The result is a specialized version of that generic type.
The where clause in a generic definition specifies constraints on the types that are used as arguments for type parameters in a generic type, method, delegate, or local function. Constraints can specify interfaces, base classes, or require a generic type to be a reference, value, or unmanaged type.
You can walk up the inheritance hierarchy and look for a GenericType, which is constructed from BaseType<,>
. Try:
var type = c.GetType();
Type baseType = type;
while(null != (baseType = baseType.BaseType))
{
if (baseType.IsGenericType)
{
var generic = baseType.GetGenericTypeDefinition();
if (generic == typeof(MyBase<,>))
{
var genericTypes = baseType.GetGenericArguments();
// genericTypes has the type argument used to construct baseType.
break;
}
}
}
Yeah, don't use string parsing. You can simply use BaseType.IsAssignableFrom(typeof(MyBase<,>))
(might have to reverse the BaseType
and MyBase<,>
-- I always get that confused).
It might also be easier to expose the types as properties in your base class, e.g.:
public Type T1_Type { get { return typeof(T1); } }
public Type T2_Type { get { return typeof(T2); } }
I do have to ask, why do you need to extract these type parameters? This is a code smell to me.
EDIT: I should add that you can't use IsAssignableFrom
as is for generics. Check out this answer for a full solution: How To Detect If Type is Another Generic Type
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With