2011-03-25 149 views
16

在類和方法定義中,可以添加類型約束,如where T : IFoo類型約束的反射

是否可以通過System.TypeMethodInfo來反映這些限制?到目前爲止我還沒有發現任何東西;任何幫助將不勝感激。

回答

19

您可以迭代通用參數到類型,並且對於每個參數,您可以要求輸入約束類型。

你做到這一點使用:

看看這段代碼,您可以通過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 
{ 
} 

輸出是:

 
T 

Type [] (1 item) 
typeof (Stream)

找到其他限制,如new(),你可以使用.GenericParameterAttributes標誌枚舉,例如:

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() 
{ 
} 

,輸出:

 
T 

Type [] (1 item) 
typeof (Stream) 

DefaultConstructorConstraint
+0

非常感謝!大! – 2011-03-25 13:29:12

2

使用先前發現System.Type可以使用GetGenericParameterConstraints()

這是關於Generics and Reflection的優秀MSDN文章。

+0

非常感謝! – 2011-03-25 13:26:55

0

Lasse的answer指出了相關的Type方法。我用它作爲參考,同時創造這種擴展方法:

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(); 
} 

有趣的是,似乎Type.BaseType財產上通用的參數也返回一個類型約束。