在具有多个对应名称的 enum
值上调用 ToString()
时,什么决定选择哪个名称?
问题的详细解释如下。
我已经确定这不是由以下任何一个唯一确定的:字母顺序;申报单;也不,名称长度。
例如,假设我想要一个枚举,其中数值直接对应于实际用途(例如颜色的 rgb 值)。
public enum RgbColor
{
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff
}
现在,使用此枚举,调用 default(RgbColor)
将返回黑色的 rgb 值。假设我不希望默认值为黑色,因为我希望 UI 设计人员在没有关于使用什么颜色的具体说明时能够使用对“默认”的调用。目前,UI 设计师使用的默认值实际上是“蓝色”,但这可能会改变。因此,我在枚举上添加了一个额外的 TextDefault
定义,现在它看起来像:
public enum RgbColorWithTextDefaultFirst
{
TextDefault = 0x0000ff,
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff
}
现在,我已经对此进行了测试,我发现调用 RgbColorWithTextDefaultFirst.TextDefault.ToString()
和 RgbColorWithTextDefaultFirst.Blue.ToString()
都会产生“蓝色”。所以,我认为最后声明的名称将覆盖之前声明的名称。为了验证我的假设,我写道:
public enum RgbColorWithTextDefaultLast
{
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff,
TextDefault = 0x0000ff
}
然而,令我惊讶的是,RgbColorWithTextDefaultLast.Blue.ToString()
和 RgbColorWithTextDefaultLast.TextDefault.ToString()
。我的下一个猜测是它按字母顺序对名称进行排序并返回第一个。为了测试这一点,我尝试:
public enum RgbColorWithATextDefaultFirst
{
ATextDefault = 0x0000ff,
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff
}
public enum RgbColorWithATextDefaultLast
{
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff,
ATextDefault = 0x0000ff
}
现在,对于所有四个 RgbColorWithATextDefaultFirst.ATextDefault.ToString()
,RgbColorWithATextDefaultFirst.Blue.ToString()
,RgbColorWithATextDefaultLast.ATextDefault.ToString()
,RgbColorWithATextDefaultLast.Blue.ToString()
,我以“Blue”结尾。我意识到还有另一个区别因素,即字符串的长度。我现在的猜测是,所选名称由名称字符串的长度决定。所以,我的测试是使用这些声明:
public enum RgbColorWithALast
{
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff,
A = 0x0000ff
}
public enum RgbColorWithAFirst
{
A = 0x0000ff,
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff
}
现在,猜猜我得到的所有值是什么:RgbColorWithAFirst.A.ToString()
; RgbColorWithAFirst.Blue.ToString()
; RgbColorWithALast.A.ToString()
,RgbColorWithALast.Blue.ToString()
。没错,就是“蓝”。
在这一点上,我已经放弃了试图通过猜测来弄清楚是什么决定了这一点。我打开了 Reflector,我打算看看并尝试弄清楚这个问题,但我想我会在这里问一个问题,看看这里是否有人已经知道答案,也就是:什么决定了在具有多个对应名称的 enum
值上调用 ToString()
时选择哪个名称?
最佳答案
我在这里可能走得太远了,但我认为它是由排序值的二进制搜索决定的,因此可能取决于值总数的奇偶校验。您可以通过在两者中定义另一个值来用最后一个示例(RgbColorWithAFirst
和 RgbColorWithALast
)来说明这一点 - 然后您从所有 中获得
调用。A
>ToString
我通过反编译 mscorlib
(4.0) 到达这里,并注意到最终我们在声明值的排序数组上调用了 Array.BinarySearch
。自然地,二分搜索一旦找到匹配项就会停止,因此要让它在两个相同的值之间切换,最简单的方法是通过添加一个额外的值来更改搜索树。
当然,这是一个实现细节,不应依赖。在我看来,在您的情况下,最好通过在您希望明确显示值的枚举值上使用 DescriptionAttribute
以及辅助方法,例如:
public static class EnumExtensions
{
public static string Description(this Enum value)
{
var field = value.GetType().GetField(value.ToString());
var attribute = Attribute.GetCustomAttribute(
field,
typeof (DescriptionAttribute))
as DescriptionAttribute;
return attribute == null ? value.ToString() : attribute.Description;
}
}
关于c# - 在具有多个对应名称的枚举值上调用 ToString() 时,什么决定选择哪个名称?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12711059/