我需要从我通过反射获得的某些类型中打印出枚举值及其相应的底层值。这在大多数情况下都很好用。
但是,如果枚举是在泛型类型中声明的,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/