c# - 通过泛型类中嵌套枚举的反射获取枚举值

标签 c# generics reflection enums

我需要从我通过反射获得的某些类型中打印出枚举值及其相应的底层值。这在大多数情况下都很好用。 但是,如果枚举是在泛型类型中声明的,Enum.GetValues 会抛出以下异常:

[System.NotSupportedException: Cannot create arrays of open type. ]  
at System.Array.InternalCreate(Void* elementType, Int32 rank, Int32* pLengths, Int32* pLowerBounds)    
at System.Array.CreateInstance(Type elementType, Int32 length)
at System.Array.UnsafeCreateInstance(Type elementType, Int32 length)   
at System.RuntimeType.GetEnumValues()

复制完整代码:

using System;

public class Program
{
    public static void Main()
    {
       var enumType= typeof(Foo<>.Bar);
       var underlyingType = Enum.GetUnderlyingType(enumType);
       Console.WriteLine(enumType.IsEnum);

       foreach(var value in Enum.GetValues(enumType))
       {
           Console.WriteLine("{0} = {1}", value, Convert.ChangeType(value, underlyingType));
       }
    }

}

public class Foo<T>
{
    public enum Bar
    {
        A = 1,
        B = 2
    }
}

或者测试一下here

这是期望的行为吗?我该如何解决?

构造一个类型是一种解决方法,但对我来说是 Not Acceptable ,因为它会变得太复杂。

最佳答案

Construction a type would be a workaround but inacceptable for me, since it would get too complicated.

这是获得正常行为的值的唯一方法。

您可以获取开放类型的字段,奇怪的是您可以以这种方式获取枚举的值。您应该尽量避免使用这些值,但您可以将它们转换为它们的基础类型。

public static void Main()
{
   var enumType = typeof(Foo<>.Bar);
   var underlyingType = Enum.GetUnderlyingType(enumType);

   foreach(var field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
   {
       var value = field.GetValue(null);
       var underlyingValue = Convert.ChangeType(value, underlyingType);
       Console.WriteLine($"{field.Name} = {underlyingValue}");
   }
}

但是,更好的解决方案是使用 field.GetRawConstantValue():

public static void Main()
{
   var enumType = typeof(Foo<>.Bar);

   foreach(var field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
   {
       Console.WriteLine($"{field.Name} = {field.GetRawConstantValue()}");
   }
}

那样的话,如果 CLR 被修复以防止产生这种奇怪的值,您的代码就不会中断。

关于c# - 通过泛型类中嵌套枚举的反射获取枚举值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43631445/

相关文章:

c# - 过程监控

c# - 如何以相同的输出为目标同步运行进程?

java - 反射 - 使用未知数量的构造函数参数获取未知类的新实例

c# - 使用运行时类型执行的通用方法

java - 从字节码解析类名

c# - WPF 从后台工作人员更新状态栏文本

c# - 需要帮助才能摆脱异常丛林

Java 使用泛型或类类型创建对象的新实例

Scala Generics - ADT 中的通用提取器方法

typescript - 如何在 TypeScript 中显式定义泛型返回类的返回类型?