I have an interface similar to the one below:
public interface IInterface<T>
where T : IInterface<T>
{
}
And now I need to create a type representing this interface using reflection, e.g.
typeof(IInterface<>).MakeGenericType(someType);
However, I don't actually know what type 'someType' will be until runtime, and it's possible that the type won't be valid as a type argument for the generic interface, so MakeGenericType fails.
The question is, how can I check that 'someType' is valid for the generic constraint?
You can get the Type that represents T , and use the IsInterface property: Type type = typeof(T); if (type. IsInterface) { ... } If you want to know which interface is passed, just use == to compare the Type objects, e.g.
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.
Use the IsGenericType property to determine whether the type is generic, and use the IsGenericTypeDefinition property to determine whether the type is a generic type definition. Get an array that contains the generic type arguments, using the GetGenericArguments method.
A type constraint on a generic type parameter indicates a requirement that a type must fulfill in order to be accepted as a type argument for that type parameter. (For example, it might have to be a given class type or a subtype of that class type, or it might have to implement a given interface.)
To be honest, the simplest approach would be to just call MakeGenericType
and catch the ArgumentException
that will be thrown if any type argument is wrong (or if you've got the wrong number of type parameters).
While you could use Type.GetGenericParameterConstraints
to find the constraints and then work out what each of them means, it's going to be ugly and bug-prone code.
I don't usually like suggesting "just try it and catch" but in this case I think it's going to be the most reliable approach. Otherwise you're just reimplementing the checks that the CLR is going to perform anyway - and what are the chances you'll reimplement them perfectly? :)
This is possible. Given a constraint, you use Type.GenericParameterAttributes
and the masks
GenericParameterAttributes.ReferenceTypeConstraint
GenericParameterAttributes.NotNullableValueTypeConstraint
GenericParameterAttributes.DefaultConstructorConstraint
to check for the presence of class
, struct
or new()
constraints. You can easily check if a given type satisfies these constraints (the first is easy to implement (use Type.IsClass
), the second is slightly tricky but you can do it using reflection, and the third has a little gotcha that your unit testing will detect (Type.GetConstructor(new Type[0])
doesn't return the default constructor for value types but you know those have a default constructor anyway).
After this, you use Type.GetGenericParameterConstraints
to get the type hierarchy constraints (the where T : Base, IInterface
like constraints) and run through them to check that the given type satisfies them.
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