非唯一枚举值

Rik*_*kon 51 c# enums struct

我试图掩盖edi文件中的索引位置...我有一种情况,根据情况可以在索引中有2或3个东西.使用枚举隐藏"魔术数字"会很酷,并且很惊讶你可以将多个枚举分配给相同的值,如下所示:

public enum Color
{
    Red = 1,
    Blue = 1,
    Green = 1
}
Run Code Online (Sandbox Code Playgroud)

并且编译器对此很满意.我没想到这会起作用.我不需要回到枚举,所以我不担心回去,但这闻起来很时髦.为什么CLR允许枚举的多个值,我应该使用结构吗?(结构似乎比枚举更重要,这似乎有效)

Mot*_*ked 76

实际上你已经定义了一个结构......在幕后,一个枚举只是一个结构(但它派生自System.Enum),而枚举的值被定义为常量(你可以用ILDASM来验证它).

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

public struct Color : System.Enum
{
    public const int Red = 1;
    public const int Blue = 1;
    public const int Green = 1;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码不会在C#中编译,因为编译器不允许定义具有显式基类的结构,但这是它为枚举定义发出的结果.

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

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

Color color1 = (Color)1;
Color color2 = (Color)Enum.Parse(typeof(Color), "1");
Run Code Online (Sandbox Code Playgroud)

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

此外,以下布尔值是真的,看起来有点奇怪......

// true (Red is Green??)
bool b = Color.Red == Color.Green;
Run Code Online (Sandbox Code Playgroud)

在底线这是完全合法的,但是在你有意义的时候使用它是由...

这是我的.NET教程部分的直接链接,它讨论了引擎盖下的枚举:http://motti.me/c1E

  • 我们中的一些人是红绿色盲,所以最后一行代码有完美的意义;-) (22认同)

Mar*_*ers 19

那是完全合法的C#.从C#语言规范版本4.0,第14.3节:

多个枚举成员可以共享相同的关联值.这个例子

enum Color 
{
   Red,
   Green,
   Blue,
   Max = Blue
}
Run Code Online (Sandbox Code Playgroud)

显示一个枚举,其中两个枚举成员 - 蓝色和最大 - 具有相同的关联值.


Alo*_*aus 11

相同的数值但不同的名称不是别名.它可能是例如

public enum Color
{
   DefaultColor = 1,
   Red = 1,
   Blue = 2
}
Run Code Online (Sandbox Code Playgroud)

在某些情况下它可能有意义但不是很多.当您解析值并调用colorValue.ToString()时,您将获得最后一个值作为字符串值返回(在这种情况下为红色)但是您将丢失默认颜色的概念,因为它是相同的东西.至少在你建模数据的方式上.如果要将其分开,请为不同的事物使用不同的值.

  • 这是一个很好的“为什么”示例:因为您想枚举值,但还要命名默认值(或最小值/最大值)。 (2认同)

Phi*_*hil 5

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

public enum AllTheThings
{
    TheMoney = 1,
    TheFreeRides = 1,
    TheLieThatYouDenied = 2,
    TheCallsYouveBeenMaking = 3,
    TheTimesYouveBeenFaking = 4
}
Run Code Online (Sandbox Code Playgroud)

  • this.Collection.Select(c => c.Rise()); (2认同)

Ste*_*nds 5

需要注意的一件事是,如果您依赖 C# 自动分配枚举值,那么任何别名成员的顺序就变得很重要。考虑以下:

public enum Foo
{
    Alpha,  // 0
    Bravo,  // 1
    Charlie,  // 2
    Delta,  // 3
}
Run Code Online (Sandbox Code Playgroud)

如果您在其中添加别名,它将重置该位置的自动编号

public enum Foo
{
    Alpha,  // 0
    Bravo,  // 1
    Charlie,  // 2
    AlsoBravo = Bravo,  // AlsoBravo assigned 1, same as Bravo
    Delta,  // Delta is now 2, not 3 as you might expect
}
Run Code Online (Sandbox Code Playgroud)

通常这不是问题,因为别名成员直接位于它们所别名的成员之后。这很好并且按预期工作:

public enum Foo
{
    Alpha,  // 0
    Bravo,  // 1
    AlsoBravo = Bravo,  // AlsoBravo assigned 1, same as Bravo
    Charlie,  // Continues with 2, as expected
    Delta,  // 3
}
Run Code Online (Sandbox Code Playgroud)

这个问题今天困扰了我,因为我有一个枚举,其成员具有我不想重复的属性,类似于以下内容:

public enum AppIcon
{
    [IconMapping(Icon.Cogs)] MenuItem_AppSettingsTab,  // 0
    [IconMapping(Icon.TabRemove)] MenuItem_CloseTab,  // 1

    RootTab_AppSettings = MenuItem_AppSettingsTab,  // 0
    [IconMapping(Icon.Cube)] RootTab_Package,  // 1 not 3, oops!
}
Run Code Online (Sandbox Code Playgroud)