如何获取数组中方法中使用的泛型类型?

时间:2014-06-25 18:42:08

标签: c# .net generics reflection types

我有这种通用方法,我想确保指定的类型是枚举。 现在我知道我不能做where T:enum之类的事情。但我想在运行时确保。

我知道我可以像typeof(T).IsENum那样做。但我想使用像这样的反射

public static List<Tuple<T, Y>> Produce<T, Y>()
    where T: struct, IConvertible
    where Y: struct, IConvertible
{
    var methodInfo = System.Reflection.MethodBase.GetCurrentMethod();
    foreach(var typeInMethod in methodInfo.GetGenericArguments()) 
        CheckTypeIsEnum(typeInMethod);

问题是methodInfo.GetGenericArguments()返回的类型不是我指定的枚举类型。但它们的类型为TYBaseType: {Name = "ValueType" FullName = "System.ValueType"}

总结:如何获取方法中使用的所有泛型类型的数组?

P.S。 .Net 4.5

1 个答案:

答案 0 :(得分:7)

您应该使用typeof(T)typeof(Y) - 这些将为您提供实际泛型类型参数。在这里使用反射没有任何好处:它很慢并且会给你错误的答案!据我所知,泛型类型参数在执行时只能用于反射。特别是,您当前正在调用的方法(MethodBase.GetCurrentMethod)明确表明您的方法不起作用:

  

如果当前正在执行的方法是通用方法,GetCurrentMethod将返回通用方法定义

(换句话说,没有指定类型参数的版本 - 它只知道你有TY,但不知道它们是什么。)

所以只需摆脱你的循环,然后使用:

CheckTypeIsEnum(typeof(T));
CheckTypeIsEnum(typeof(Y));

另请注意,如果有一点IL hackery,可以约束where T : enum。它不是有效的C#,但它是有效的IL,而C#编译器遵循它正在查看的IL中的约束:)请参阅我的Unconstrained Melody项目中的示例。