2011-07-25 17 views
13

我有以下枚举定义(在C#):Enum.GetNames()导致负枚举意想不到为了常数

public enum ELogLevel 
{ 
    General = -1, // Should only be used in drop-down box in Merlinia Administrator log settings 
    All = 0,  // Should not be used as a level, only as a threshold, effectively same as Trace 
    Trace = 1, 
    Debug = 2, 
    Info = 3, 
    Warn = 4, 
    Error = 5, 
    Fatal = 6, 
    Off = 7  // Should not be used as a level, only as a threshold 
} 

现在,当我对这个类型做一个Enum.GetNames()我得到一个字符串数组如预期的9个元素,但顺序是All,Trace,...,Off,General,这不是我所期待的。

这里的MSDN documentationEnum.GetNames()

“备注:返回值数组的元素由枚举常量的 值进行排序。”

这是怎么回事?我可以改变我的程序来考虑这个“功能”,但我想知道为什么.NET正在做它正在做的事情。

+0

我会建议向微软提交一个错误报告。 –

+0

它不再是一个错误,它是一个功能[现在记录](http://msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx):“数组的元素被排序通过枚举常量的二进制值(**,即它们的无符号数值**)。“ – jason

回答

17

这是一个既GetNames()GetValues()已知的bug已报告here,但最终得到封闭,不会解决:

没错,这的确方法有它返回枚举值的分类为无符号类型的数组中的错误(-2是0xFFFFFFFE和-1是0xFFFFFFFF的二进制补码,这就是为什么它们出现在列表的末尾)而不是返回值s按其签名类型排序。

不幸的是,我们无法更改排列顺序的GetValues的,因为我们将打破已写入依赖于当前排序行为的所有现有的.NET程序[...]

看起来你必须自己重新排列这些值。

+0

“已编写的现有.NET程序依赖于当前的排序行为”,这就是为什么你不会徘徊在实现细节上。 – BoltClock

+1

当然,如果这种实现总是被一直以来会被破坏的话,那么MS就会更新文档,使其与实际行为相匹配。 – LukeH

+0

@LukeH:的确如此。即使是臭虫记者也是这样说的。 – BoltClock

2

根据排序如何发生时,它可以是如同它们是无符号的,它是排序的值,在这种情况下,-1 = 0xFFFFFFFF的,这是当然大于7

+1

这当然是可能的,它似乎解释了一些事情,但它肯定是奇怪的,因为'enum'的默认基础类型是'int'。 – jason

+0

看来我的猜测是由下面的BoltClock的答案证实的。 – Iridium