我有一个这样的枚举:
public enum MyEnum
{
Character = 'C',
Number = 'N',
}
然后我正在做这样的事情:
char myChar = 'C';
var value = Enum.GetName(typeof(MyEnum), myChar); //throw exception on .NET 3.5 or less
此代码在使用.NET 4的项目中正常,但在.NET 3.5或更低版本上引发异常。这是例外:
传入的值必须是枚举基础或基础类型 枚举,例如Int32.Parameter name:value
所以我用.NET 4发布了我的项目并与我的朋友分享并告诉他们他们需要.NET4。他们成功地运行程序但是发现程序在某些系统上抛出相同的异常,即使使用.NET 4也是如此!任何人都知道这个异常的原因是什么?
我用这种方式解决了这个问题,但有兴趣知道为什么它在某些系统上工作而不在其他系统上工作? (所有这些都有.NET4)
var value = Enum.GetName(typeof(MyEnum), (int)myChar);
答案 0 :(得分:8)
这在.NET 4.5中已更改。请注意,很难看到您是否在计算机上安装了4.0或4.5,4.5 替换 4.0并使用与4.0相同的安装目录。
更改的方法是@Dirk引用的方法,即内部IsIntegerType()辅助方法。 4.0版本看起来像这样:
internal static bool IsIntegerType(Type t)
{
if (((!(t == typeof(int)) && !(t == typeof(short))) && (!(t == typeof(ushort)) &&
!(t == typeof(byte)))) && ((!(t == typeof(sbyte)) && !(t == typeof(uint))) &&
!(t == typeof(long))))
{
return (t == typeof(ulong));
}
return true;
}
注意typeof(char)是如何测试的,所以它不认为它是传递给Enum.GetName()的 value 参数的有效类型。
.NET Framework版本中的这种类型的更改并非并行版本,但它确实很难诊断程序失败。特别是因为您在项目中以.NET 4.0为目标,但最终在安装了4.5的机器上运行,所以从未注意到问题。但kaboom在安装了4.0的机器上。
最好的旋转,它是4.0中的一个错误,他们修复了4.5。坦率地说,你当然希望一个char完全有效,因为那是你用来初始化枚举成员的东西。它确实显示了微软修复错误的难度。
答案 1 :(得分:3)
Enum.GetName
的实现已从2.0更改为4.0。
这是2.0(使用ILSpy)的反编译版本:
public static string GetName(Type enumType, object value)
{
[...]
// Enum.intType = typeof(int)
Type type = value.GetType();
if (type.IsEnum || type == Enum.intType || type == typeof(short) || type == typeof(ushort) || type == typeof(byte) || type == typeof(sbyte) || type == typeof(uint) || type == typeof(long) || type == typeof(ulong))
{
return Enum.InternalGetValueAsString(enumType, value);
}
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
}
您可以看到type = typeof(char)
此异常是throw。
对于4.0,它是:
public static string GetName(Type enumType, object value)
{
[...]
// this is actually in a method called by GetName, I put it here for clarity
Type type = value.GetType();
if (!type.IsEnum && !Type.IsIntegerType(type))
{
throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");
}
[...]
}
// Type.IsIntegerType
internal static bool IsIntegerType(Type t)
{
return t == typeof(int) || t == typeof(short) || t == typeof(ushort) || t == typeof(byte) || t == typeof(sbyte) || t == typeof(uint) || t == typeof(long) || t == typeof(ulong) || t == typeof(char) || t == typeof(bool);
}
但是这里type = typeof(char)
不会导致异常。
答案 2 :(得分:1)
枚举的已批准类型为byte, sbyte, short, ushort, int, uint, long, or ulong
MSDN。
您无法创建Enum char值,.NET允许您执行此操作,但是编译器会将您的char值转换为其等效的int表示(ASCII)。