Reflection over Type Constraints
In cl开发者_运维技巧ass and method definitions, it's possible to add type constraints like where T : IFoo
.
Is it possible to reflect over those constraints with System.Type
or MethodInfo
? I haven't found anything so far; any help will be appreciated.
You can iterate through the generic parameters to the type, and for each parameter, you can ask for the constraint types.
You do this using:
- Type.GetGenericArguments of Type to find the generic arguments to the type, ie.
Type<T>
, you would findT
. - Type.GetGenericParameterConstraints gives you the base types that each such parameter is constrained against, you call this on the arguments you find from the above method.
Take a look at this code, which you can run through LINQPad:
void Main()
{
Type type = typeof(TestClass<>);
foreach (var parm in type.GetGenericArguments())
{
Debug.WriteLine(parm.Name);
parm.GetGenericParameterConstraints().Dump();
}
}
public class TestClass<T>
where T : Stream
{
}
The output is:
T Type [] (1 item) typeof (Stream)
To find other constraints, such as new()
, you can use the .GenericParameterAttributes
flags enum, example:
void Main()
{
Type type = typeof(TestClass<>);
foreach (var parm in type.GetGenericArguments())
{
Debug.WriteLine(parm.Name);
parm.GetGenericParameterConstraints().Dump();
parm.GenericParameterAttributes.Dump();
}
}
public class TestClass<T>
where T : new()
{
}
Which outputs:
T Type [] (1 item) typeof (Stream) DefaultConstructorConstraint
You can use the GetGenericParameterConstraints() method to do that.
Using a previously found System.Type
you can use GetGenericParameterConstraints()
.
Here's an excellent MSDN article on Generics and Reflection.
Lasse's answer points out the relevant Type
methods. I used it as a reference while creating this extension method:
public static IList<Tuple<Type, Type[], GenericParameterAttributes>> GetTypeConstraints( this Type type )
{
return type.GetGenericArguments()
.Select( t => Tuple.Create( t, t.GetGenericParameterConstraints(), t.GenericParameterAttributes ) )
.Where( t => t.Item2.Length > 0 || t.Item3 > GenericParameterAttributes.None )
.ToList();
}
Interestingly, it seems that the Type.BaseType
property on a generic parameter also returns a single type constraint.
精彩评论