Enum.GetName的奇怪行为

Hos*_*Rad 7 c# enums exception-handling .net-4.0

我有这样的枚举:

public enum MyEnum
{
    Character = 'C',
    Number = 'N',
}
Run Code Online (Sandbox Code Playgroud)

然后我做这样的事情:

char myChar = 'C';
var value = Enum.GetName(typeof(MyEnum), myChar); //throw exception on .NET 3.5 or less
Run Code Online (Sandbox Code Playgroud)

这个代码在使用.NET 4的项目中没问题,但在.NET 3.5或更低版本上抛出异常.这是例外:

传入的值必须是枚举基础或枚举的基础类型,例如Int32.Parameter name:value

所以我用.NET 4发布了我的项目并与我的朋友分享并告诉他们他们需要.NET4.他们成功运行程序,但发现程序在某些系统上抛出相同的异常,即使使用.NET 4!任何人都知道这个例外的原因是什么?

我以这种方式解决了这个问题,但有兴趣知道为什么它在某些系统上工作而不在其他系统上工作?(所有这些都有.NET4)

var value = Enum.GetName(typeof(MyEnum), (int)myChar);
Run Code Online (Sandbox Code Playgroud)

Han*_*ant 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;
}
Run Code Online (Sandbox Code Playgroud)

注意typeof(char)是如何测试的,所以它不认为它是传递给Enum.GetName()的value参数的有效类型.

.NET Framework版本中的这些更改不是并行版本,相当不太酷,它确实很难诊断程序失败.特别是因为您在项目中以.NET 4.0为目标,但最终在安装了4.5的机器上运行,所以从未注意到问题.但kaboom在一台只安装了4.0的机器上.

最好的旋转,它是4.0中的一个错误,他们修复了4.5.坦率地说,你当然希望char完全有效,因为那是你用来初始化枚举成员的东西.它确实显示了微软修复错误的难度.

  • 是的,他们的版本号仍然是4.0.0.0.只有4.5中添加的版本具有4.5.0.0版本号.我不得不从旧机器上复制4.0版本的mscorlib.dll来写这个答案. (2认同)