【问题标题】:How to get the generic types used in a method in an array?如何获取数组中方法中使用的泛型类型?
【发布时间】:2014-06-25 18:42:08
【问题描述】:

我有这个通用方法,我想确保指定的类型是枚举。 现在我明白我不能做类似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"}

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

附: .Net 4.5

【问题讨论】:

    标签: c# .net generics reflection types


    【解决方案1】:

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

    如果当前执行的方法是泛型方法,GetCurrentMethod 返回泛型方法定义

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

    所以只要摆脱你的循环,并使用:

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

    还请注意,通过一点 IL 黑客技术,您可以拥有where T : enum 的约束。它不是有效的 C#,但它是有效的 IL,并且 C# 编译器遵循它正在查看的 IL 中的约束:) 请参阅我的 Unconstrained Melody 项目以获取示例。

    【讨论】:

    • 我明确没有要求typeof(T)。如果可能的话,我想要反思。不过,您链接到的项目似乎很有趣。
    • @MikedeKlerk:为什么你不想要typeof(T)?这给了你正确的答案,而反射根本没有……因为当你得到一个泛型方法定义(这是你将从GetCurrentMethod 得到的)时,根本就没有任何泛型类型参数。使用有效的解决方案:)
    • @MikedeKlerk:我添加了更多信息,说明您当前的方法为何不起作用。
    • 感谢您的额外说明。我只是为具有 6 个通用参数的函数编写了额外的行。我以为我只是找不到它。但你说这是不可能的。看到你的 C# 技术背景,我想我不必再看了,因为这是不可能的(在 VS 中按原样使用 C#)。
    • @MikedeKlerk:如果你在多个地方都有这个,你总是可以编写具有可变数量的类型参数的辅助方法,只是验证它们,例如致电ValidateEnums&lt;T, Y&gt;ValidateEnums&lt;T1, T2, T3, T4, T5, T6&gt;。这样至少不会弄乱代码。
    猜你喜欢
    • 2013-04-17
    • 2019-05-15
    • 1970-01-01
    • 2015-06-08
    • 1970-01-01
    • 1970-01-01
    • 2018-11-06
    • 2019-12-22
    • 1970-01-01
    相关资源
    最近更新 更多