我有这种通用方法,我想确保指定的类型是枚举。
现在我知道我不能做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()返回的类型不是我指定的枚举类型。但它们的类型为T
,Y
和BaseType: {Name = "ValueType" FullName = "System.ValueType"}
。
总结:如何获取方法中使用的所有泛型类型的数组?
P.S。 .Net 4.5
答案 0 :(得分:7)
您应该使用typeof(T)
和typeof(Y)
- 这些将为您提供实际泛型类型参数。在这里使用反射没有任何好处:它很慢并且会给你错误的答案!据我所知,泛型类型参数在执行时只能用于反射。特别是,您当前正在调用的方法(MethodBase.GetCurrentMethod
)明确表明您的方法不起作用:
如果当前正在执行的方法是通用方法,
GetCurrentMethod
将返回通用方法定义。
(换句话说,没有指定类型参数的版本 - 它只知道你有T
和Y
,但不知道它们是什么。)
所以只需摆脱你的循环,然后使用:
CheckTypeIsEnum(typeof(T));
CheckTypeIsEnum(typeof(Y));
另请注意,如果有一点IL hackery,可以约束where T : enum
。它不是有效的C#,但它是有效的IL,而C#编译器遵循它正在查看的IL中的约束:)请参阅我的Unconstrained Melody项目中的示例。