简体   繁体   English

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

[英]How to get the generic types used in a method in an array?

I've got this generic method, and I want to make sure that the types specified are enums. 我已经有了这种通用方法,并且我想确保指定的类型是枚举。 Now I understand I can't do something like where T:enum . 现在我知道我不能做where T:enum类的事情。 But I want to make sure in runtime. 但是我要确保在运行时。

I know I could do it like typeof(T).IsENum . 我知道我可以像typeof(T).IsENum But I want to use reflection like so 但我想像这样使用反射

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

The problem is that the types returned by methodInfo.GetGenericArguments() aren't of the enum types I specified. 问题是methodInfo.GetGenericArguments()返回的类型不是我指定的枚举类型。 But instead they are of type T and Y and BaseType: {Name = "ValueType" FullName = "System.ValueType"} . 但是,它们的类型为TY并且为BaseType: {Name = "ValueType" FullName = "System.ValueType"}

Summarized: How do I get an array of all generic types used in the method? 总结:如何获得该方法中使用的所有泛型类型的数组?

PS .Net 4.5 PS .Net 4.5

You should just use typeof(T) and typeof(Y) - those will give you the actual generic type arguments. 您应该只使用typeof(T)typeof(Y) -这些将为您提供实际的泛型类型参数。 There's no benefit to using reflection here: it's slow and gives you the wrong answers! 在这里使用反射没有任何好处:它很慢并且会给您错误的答案! As far as I'm aware, the generic type arguments simply aren't available with reflection at execution time. 据我所知,泛型类型参数根本无法在执行时进行反射。 In particular, the method you're currently calling ( MethodBase.GetCurrentMethod ) explicitly documents that your approach will not work: 特别是,您当前正在调用的方法( MethodBase.GetCurrentMethod )明确记录了您的方法无效:

If the currently executing method is a generic method, GetCurrentMethod returns the generic method definition . 如果当前执行的方法是通用方法,则GetCurrentMethod返回通用方法定义

(In other words, the version which doesn't have the type arguments specified - it only knows that you've got T and Y , but not what they are.) (换句话说,没有指定类型参数的版本-它仅知道您具有TY ,但不知道它们是什么。)

So just get rid of your loop, and use: 因此,只需摆脱循环,并使用:

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

Also note that with a bit of IL hackery, you can have a constraint of where T : enum . 还要注意,由于使用了一些IL黑客手段,您可以限制where T : enum It's not valid C#, but it's valid IL and the C# compiler obeys the constraint in IL it's looking at :) See my Unconstrained Melody project for an example. 它不是有效的C#,但它是有效的IL,并且C#编译器遵循它正在查看的IL中的约束:)有关示例,请参阅我的Unconstrained Melody项目。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM