sma*_*man 15 .net c# clr enums tostring
ToString()的enum值时,什么决定选择哪个名称?问题的详细解释如下.
我已经确定这不是由以下任何一个唯一确定的:字母顺序; 申报单; 名字长度.
例如,考虑我想要一个枚举,其中数值直接对应于实际用途(例如颜色的rgb值).
public enum RgbColor
{
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff
}
Run Code Online (Sandbox Code Playgroud)
现在,使用此枚举,调用default(RgbColor)将返回黑色的rgb值.假设我不希望默认值为黑色,因为我希望UI设计者能够在没有关于使用什么颜色的具体说明时使用"默认"调用.目前,要使用的UI设计器的默认值实际上是"蓝色",但这可能会改变.所以,我TextDefault在枚举上添加了一个额外的定义,现在它看起来像:
public enum RgbColorWithTextDefaultFirst
{
TextDefault = 0x0000ff,
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff
}
Run Code Online (Sandbox Code Playgroud)
现在,我已经测试了这个,我发现调用RgbColorWithTextDefaultFirst.TextDefault.ToString()并且RgbColorWithTextDefaultFirst.Blue.ToString()都产生"蓝色".所以,我认为最后声明的名称将覆盖先前声明的名称.为了测试我的假设,我写道:
public enum RgbColorWithTextDefaultLast
{
Black = 0x000000,
Red = 0xff0000,
Green = 0x00ff00,
Blue = 0x0000ff,
White = 0xffffff,
TextDefault = 0x0000ff
}
Run Code Online (Sandbox Code Playgroud)
然而,令我惊讶的是,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
}
Run Code Online (Sandbox Code Playgroud)
现在,所有四个RgbColorWithATextDefaultFirst.ATextDefault.ToString(),RgbColorWithATextDefaultFirst.Blue.ToString(),RgbColorWithATextDefaultLast.ATextDefault.ToString(),RgbColorWithATextDefaultLast.Blue.ToString(),我结束了"蓝色".我意识到还有另一个区别因素,即字符串的长度.我的猜测是,所选名称由名称字符串的长度决定.所以,我的测试是使用这些声明:
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
}
Run Code Online (Sandbox Code Playgroud)
现在,你猜怎么着价值我得到了所有的:RgbColorWithAFirst.A.ToString(); RgbColorWithAFirst.Blue.ToString(); RgbColorWithALast.A.ToString(),RgbColorWithALast.Blue.ToString().那是对的,"蓝色".
在这一点上,我已经放弃试图通过猜测来弄清楚是什么决定了这一点.我打开了反射器,我打算看看并尝试解决这个问题,但我想我会在这里问一个问题,看看这里是否有人已经知道答案了,这又是:什么决定了这个名字是什么在调用具有多个相应名称ToString()的enum值时选择?
我可能在这里走得太远了,但我认为它是通过二进制搜索排序值来决定的,因此可以取决于值总数的奇偶性.您可以通过在最后一个示例(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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
440 次 |
| 最近记录: |