2011-11-07 159 views
34

我试图掩盖edi文件中的索引位置......我有一种情况,其中2或3件事情可能是基于情况的索引。这将会是很酷的使用枚举隐藏“幻数”,并惊讶地看到,你可以指定多个枚举,以这样的值相同:非唯一的枚举值

public enum Color 
{ 
    Red = 1, 
    Blue = 1, 
    Green = 1 
} 

和编译器很高兴与此有关。我没有想到这会起作用。我不需要退回到枚举,所以我不担心试图返回,但这闻起来时髦。为什么CLR允许多个枚举值,我应该使用一个结构呢? (结构似乎比枚举更重,这似乎工作)

+2

这总是最好用相反回答过的问题:为什么会*不*允许这样做?当你说包括First和Last的enum成员时,它非常方便。 –

+1

如何使用“struct for this”? – wiero

+0

我可以使用一个结构来获得枚举“外观”,我不必投。就像“公共静态诠释红色{得到{返回1;}}” – Rikon

回答

58

其实你的'已经定义了一个结构......在幕后枚举只是一个结构(但是从System.Enum派生)和枚举值被定义为常量(可以用ILDASM来验证)。

你枚举定义转换为以下伪C#代码:

public struct Color : System.Enum 
{ 
    public const int Red = 1; 
    public const int Blue = 1; 
    public const int Green = 1; 
} 

上面的代码将不会在C#编译,因为编译器不允许界定具有明确的基类的一个结构,但是这就是它发出一个枚举定义。

由于包含多个具有相同值的常量的类型没有问题,所以枚举定义没有问题。

但由于enum没有唯一值,所以在转换为此枚举时可能会遇到问题。 例如,以下两行代码将返回枚举值Red,因为第一个值是任意选择的。

Color color1 = (Color)1; 
Color color2 = (Color)Enum.Parse(typeof(Color), "1"); 

严格来说,枚举值不是红色,它是1,但是当你打印出来的值,你会看到红色。

此外,下面的布尔是真实的,看起来有点怪......

// true (Red is Green??) 
bool b = Color.Red == Color.Green; 

在底线,这是完全合法的,但它给你当它是有道理的使用它...

这里是直接链接到我的.NET教程的发动机罩下的讨论枚举部分:http://motti.me/c1E

+0

另见:http://stackoverflow.com/questions/1425777/how-to-prevent-duplicate-values-in-enum – LosManos

+16

我们有些人红绿色的色盲,所以最后一行代码非常有意义;-) – theMayer

7

的数值相同,但不同的名称是什么都没有的别名。它可以是例如

public enum Color 
{ 
    DefaultColor = 1, 
    Red = 1, 
    Blue = 2 
} 

它可以在某些情况下有意义但不是很多。当你解析这些值并调用colorValue.ToString()时,你会得到最后一个值作为字符串化的值(在这种情况下为红色),但是由于它是相同的事物,所以你将会丢失默认颜色的圆圈。至少按照您对数据进行建模的方式进行。如果你想分开使用不同的值来处理不同的事情。

+1

这是一个很好的“为什么”的例子:因为你想枚举值,但也可以命名为默认值(或最小值/最大值)。 –

11

这是完全合法的C#。从C# Language specification版本4.0开始,第14.3节:

多个枚举成员可能共享相同的关联值。该示例

enum Color 
{ 
    Red, 
    Green, 
    Blue, 
    Max = Blue 
} 

示出了一个枚举,其中两个枚举成员 - 蓝和Max-具有相同 关联值。

3

如果您将每个枚举值看作一个常量,这是有道理的。没有理由为什么你不应该能有两个常量具有相同的值:

public enum MyColor 
{ 
    Blue = 2,   
    Yellow = 3, 
    Green = 4 
    BlueAndYellow = 4,   
} 

是一样的:

public enum MyColor 
{ 
    Blue = 2,   
    Yellow = 3, 
    Green = 4, 
    BlueAndYellow = Green,   
} 

基本上你只是有相同的两个不同的名称不变。 BlueAndYellowGreen的别名。

1

这里需要注意的一点是,非唯一值会导致Visual Studio设计器中丢失和重复的值。

public enum MyColor 
{ 
Red= 1, 
Green= 1, 
Blue= 2 
} 

如果您在browable属性中使用枚举你会看到绿,青,蓝的设计师,而不是红,绿,蓝

+0

尽管有用的信息,这不会回答这个问题 - 它会更适合作为评论(你很快就会有足够的代表张贴) – GHC

4

这将是一个完全可以接受的定义:

public enum AllTheThings 
{ 
    TheMoney = 1, 
    TheFreeRides = 1, 
    TheLieThatYouDenied = 2, 
    TheCallsYouveBeenMaking = 3, 
    TheTimesYouveBeenFaking = 4 
} 
+2

this.Collection.Select(c => c.Rise()); – Jonathan

+0

嘿!这是我的代码行! – Phil

+0

我相信这会让它进入'两个独立学科合并'列表的前5名 – radsdau