开发者

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 find T.
  • 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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜