在具有多个对应名称的枚举值上调用ToString()时,由什么决定选择哪个名称? [英] What determines which name is selected when calling ToString() on an enum value which has multiple corresponding names?

查看:43
本文介绍了在具有多个对应名称的枚举值上调用ToString()时,由什么决定选择哪个名称?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问题的详细解释如下.

我确定这不是由以下任何一项唯一确定的:字母顺序;申报单;也不是名字的长度.

I have determined that this not determined uniquely by any of: alphabetical order; declaration order; nor, name length.

例如,考虑到我想拥有一个枚举,其中的数值直接对应于实际用途(例如,颜色的rgb值).

For example, consider that I want to have an enum where the numeric values correspond directly to a practical use, (e.g. rgb values for color).

public enum RgbColor 
{
    Black   = 0x000000,
    Red     = 0xff0000,
    Green   = 0x00ff00,
    Blue    = 0x0000ff,
    White   = 0xffffff
}

现在,使用此枚举,调用 default(RgbColor)将返回黑色的rgb值.假设我不希望默认值为黑色,因为我希望UI设计人员在没有关于使用哪种颜色的特定说明时,能够使用对默认"的调用.目前,UI设计人员要使用的默认值实际上是蓝色",但是可能会发生变化.因此,我在枚举上添加了一个附加的 TextDefault 定义,现在看起来像:

Now, with this enum, calling default(RgbColor) will return the rgb value for black. Let's say I don't want the default value to be black, because I want UI designers to be able to use a call to "Default" when they don't have specific instructions about what color to use. For now, the Default value for UI designers to use is actually "Blue", but that could change. So, I add an additional TextDefault definition on the enum, and now it looks like:

public enum RgbColorWithTextDefaultFirst
{
    TextDefault = 0x0000ff,
    Black   = 0x000000,
    Red     = 0xff0000,
    Green   = 0x00ff00,
    Blue    = 0x0000ff,
    White   = 0xffffff
}

现在,我已经对此进行了测试,发现调用 RgbColorWithTextDefaultFirst.TextDefault.ToString() RgbColorWithTextDefaultFirst.Blue.ToString()都会产生蓝色".因此,我认为最后声明的名称将覆盖之前声明的名称.为了检验我的假设,我写道:

Now, I have tested this and I find that calling RgbColorWithTextDefaultFirst.TextDefault.ToString() and RgbColorWithTextDefaultFirst.Blue.ToString() both yield "Blue". So, I figured that the name that is declared last will overwrite the name of the previous declarations. To test my assumption, I wrote:

public enum RgbColorWithTextDefaultLast
{
    Black   = 0x000000,
    Red     = 0xff0000,
    Green   = 0x00ff00,
    Blue    = 0x0000ff,
    White   = 0xffffff,
    TextDefault = 0x0000ff 
}

但是,令我惊讶的是, RgbColorWithTextDefaultLast.Blue.ToString() RgbColorWithTextDefaultLast.TextDefault.ToString().我的下一个猜测是,它按字母顺序对名称进行排序并返回第一个.要对此进行测试,我尝试:

However, to my surprise, RgbColorWithTextDefaultLast.Blue.ToString() and RgbColorWithTextDefaultLast.TextDefault.ToString(). My next guess is that it sorts the names by alphabetical order and returns the first one. To test this I try:

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(),我最后得到的是蓝色".我意识到还有另一个区别因素,那就是字符串的长度.我的猜测是,所选名称取决于名称字符串的长度.因此,我的测试是使用以下声明:

Now, for all four of RgbColorWithATextDefaultFirst.ATextDefault.ToString(), RgbColorWithATextDefaultFirst.Blue.ToString(), RgbColorWithATextDefaultLast.ATextDefault.ToString(), RgbColorWithATextDefaultLast.Blue.ToString(), I end up with "Blue". I realize that there is another distinguishing factor, which is length of the string. My guess is now that the selected name is determined by the length of the name string. So, my test is to use these declarations:

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().是的,蓝色".

Now, guess what value I got for all of: RgbColorWithAFirst.A.ToString(); RgbColorWithAFirst.Blue.ToString(); RgbColorWithALast.A.ToString(), RgbColorWithALast.Blue.ToString(). That's right, "Blue".

在这一点上,我已经放弃尝试通过猜测来找出决定这一点的原因.我打开反射器,然后看一下并尝试解决这个问题,但是我想在这里问一个问题,看看这里是否有人已经知道答案了,再次是:什么决定了在具有多个对应名称的 enum 值上调用 ToString()时选择哪个名称?

At this point, I've given up on trying to figure out what determines this by guessing. I opened up reflector, and I'm going to take a look and try to figure this out, but I figured I would ask a question here to see if anyone here already knows the answer, which is, again: What determines which name is selected when calling ToString() on an enum value which has multiple corresponding names?

推荐答案

我在这里可能做得太过分了,但是我认为这是由对排序值的二进制搜索决定的,因此可以取决于值总数.您可以在最后一个示例( RgbColorWithAFirst RgbColorWithALast )中进行说明,方法是在这两个示例中都定义另一个值-然后从所有中获得 A > ToString 调用.

I might be going too far here, but I think it's decided by binary search of the sorted values, and so can depend on the parity of the total number of values. You can illustrate this with your last example (RgbColorWithAFirst and RgbColorWithALast) by defining another value in both - then you get A from all the ToString invocations.

我是通过反编译 mscorlib (4.0)并注意到最终,我们最终对声明值的排序数组上的 Array.BinarySearch 进行调用的.自然,二进制搜索一旦匹配就会停止,因此要使其在两个相同的值之间切换,最简单的方法是通过添加一个额外的值来更改搜索树.

I got here by decompiling mscorlib (4.0) and noting that eventually we get to a call to Array.BinarySearch on a sorted array of the declared values. Naturally, the binary search stops as soon as it gets a match, so to get it to switch between two identical values the easiest way is to alter the search tree, by adding an extra value.

当然,这是一个实现细节,不应依赖.在我看来,在您的情况下,最好对要明确显示值的枚举值使用 DescriptionAttribute ,并使用诸如以下方法的辅助方法来获得最好的服务:

Of course, this is an implementation detail and should not be relied on. It seems to me that in your case you would be best served by using DescriptionAttribute on enum values where you want to be explicit about the display value, and a helper method such as:

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;
    }
}

这篇关于在具有多个对应名称的枚举值上调用ToString()时,由什么决定选择哪个名称?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆