Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/cocoa/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么一个枚举可以有两个具有相同数值的不同名称?_C#_Enums - Fatal编程技术网

C# 为什么一个枚举可以有两个具有相同数值的不同名称?

C# 为什么一个枚举可以有两个具有相同数值的不同名称?,c#,enums,C#,Enums,我刚刚发现了一个微妙的错误,我有一个枚举,其中两个名称不必要地共享同一个数值(在本例中,red=10和crimson=10)。我有点惊讶这不是语法错误 public enum Colour { Red=10, Blue=11, Green=12, Crimson=10 } // Debug.Write(Colour.Red==Colour.Crimson) outputs True 这个行为可能是有用的,或者确实认为它应该是语法错误,这有什么现实原因吗?枚举是常

我刚刚发现了一个微妙的错误,我有一个枚举,其中两个名称不必要地共享同一个数值(在本例中,red=10和crimson=10)。我有点惊讶这不是语法错误

public enum Colour
{
    Red=10,
    Blue=11,
    Green=12,
    Crimson=10
}
// Debug.Write(Colour.Red==Colour.Crimson) outputs True

这个行为可能是有用的,或者确实认为它应该是语法错误,这有什么现实原因吗?

枚举是常量变量的枚举,您可以有两个值相同的项,我认为没有理由出现语法错误,但是,这将导致此代码中的编译错误

switch(c)
{
  Colour.Red:
     break;
  Colour.Crimson:
     break;
  ...
}

我在.net TWAIN包装器中也看到了同样的情况-它允许所有TWAIN消息代码存储在一个大的枚举中,但一开始确实会让事情变得有点混乱。

枚举的使用方式与constans类似,您肯定可以在相同的位置使用两个具有相同值的常量。这可能是因为第三方API,因为向后兼容性,而不仅仅是因为业务规则。

没关系。您可以有两个不同于API用户观点的值,但在功能上可以视为相同的值。

这不是语法错误。
enum
所做的就是以强类型方式枚举一系列常量

public enum Colour
{
    Red=10,
    Rouge=10,
    Blue=11,
    Bleu=11,
    Green=12,
    Vert=12,
    Black=13,
    Noir=13
}
因此,如果开发人员键入错误(如您的示例中),就CLR而言,这是一种完全有效的情况。CLR假设开发人员知道自己在做什么,以及为什么选择这样做


至于现实世界中的案例,我一时冲动想不出什么,但我仍然确信,在某些情况下,它可能会有所帮助。

当然会有,尽管它可能不太常见。如果有一个实体/值通常以两个不同的名称命名,那么这就是一个很好的理由

您所介绍的场景可能就是这样一种情况。一个更好的,直接来自BCL的,是enum;
Stop
Error
Hand
成员都具有相同的描述和值<代码>星号和
信息
也完全相同,如注释所示:

Asterisk    The message box contains a symbol consisting of a lowercase letter i in a circle.
Information The message box contains a symbol consisting of a lowercase letter i in a circle.

希望这能让您对合适的场景有一个很好的了解(您自己可能就是其中之一)。

我已经看到此功能有时用于“默认”值:


但请注意,这只是enum用户的糖分。仅仅因为它被称为默认值,并不意味着它是初始值。

使用按命名值而不是实际值是根。假设你有法语、英语等具有相同值的语言。对我来说,这是enum的根。

:

多个枚举成员可以共享相同的关联值。榜样

enum Color 
{
    Red,
    Green,
    Blue,
    Max = Blue
}
显示两个枚举成员Blue和Max具有相同关联值的枚举


在这种情况下,您可以检查MyColor==Color.Max,这在某些情况下会很有用。

有时建议(尽管MS不建议使用C#!——请参阅Salaros的评论)在枚举中包括一个下限和上限,例如

public enum Colour
{
    LowBound=10,
    Red=10,
    Rouge=10,
    Blue=11,
    Bleu=11,
    Green=12,
    Vert=12,
    Black=13,
    Noir=13,
    UpperBound=13
}

为了验证/迭代每个可能的设置。尽管我有一种感觉,.Net可能为此提供了一种工具:)

我认为重复使用同一个数字有很多用途。举一个新的例子,假设您有一个排名系统,该系统将确保特定类(父类)的对象在依赖于它的其他类(子类)之前创建,您可能有一些子类位于同一“层”,而先创建哪个并不重要。在下面的示例中,将首先创建父级,然后创建子级1、2或3,最后一个是子级4。如果将其视为树形图,则任何具有相同编号的项都将是“兄弟”

public enum ObjectRanks
{
    Parent = 0,
    Child1 = 1,
    Child2 = 1,
    Child3 = 1,
    Child4 = 2
}

虽然我能理解你的观点,这很容易出错。在这种情况下,如果VisualStudio有一个选项可以启用警告,它将允许编译,但如果相同的数字被使用两次,它将发出警告。

小心!如果
enum
具有多个具有相同值的元素,则在使用
enum.Parse()时可能会得到意外的结果。这样做将任意返回具有请求值的第一个元素。例如,如果您有
enum Car{Ford=1,Chevy=1,Mazda=1}
,那么
(Car)enum.Parse(typeof(Car),“1”)
将返回
Car.Ford
。虽然这可能有用(我不确定为什么会有用),但在大多数情况下,这可能会让人困惑(尤其是对于维护代码的工程师),或者在出现问题时容易被忽略。

这是有效的,允许使用不同的名称引用相同的值。 注意,这种方法在一个方面效果很好。如果从int/string转换为enum或格式化字符串,可能会得到不一致的结果

例如:

输出:

Crimson is Red

这个例子将说明为什么这是有用的。当你们在公共图书馆工作时,用不同的方式命名相同的东西可能会很有用

public enum GestureType
{
Touch = 1,
Tap = 1,
DoubleTouch = 2,
DoubleTap = 2,
Swipe = 3,
Slide = 3,
...
}

当不同的词在某些情况下有相同的意思时,命名它们是有意义的。解析时,在这种情况下它总是返回良好的值。

我认为它对于字段映射很有用,例如(在LinqPad中):

目的是使用较短的名称,但是Parse或TryParse的结果不一致,此代码输出:

TaskName
TaskName
IsActive
IsActive

这就是为什么这个解决方案对我很有用的原因

值得知道这一点。这是一个不故意使用股票名称的理由;具有相同值的两个名称不是错误。如果您想避免,请不要指定数值。您将如何使用它?在一个多语言编程团队中,每个成员都在选择自己的常量?我不知道这是一个怎样的有效答案。@Robin:就像@Noldorin一样,我看不出这有什么用处。你能举一个使用它的例子吗?罗宾,好的,但是OQ是为什么它是w
public enum GestureType
{
Touch = 1,
Tap = 1,
DoubleTouch = 2,
DoubleTap = 2,
Swipe = 3,
Slide = 3,
...
}
void Main()
{
    ((FieldName)Enum.Parse(typeof(FieldName), "Name", true)).ToString().Dump();
    ((FieldName)Enum.Parse(typeof(FieldName), "TaskName", true)).ToString().Dump();
    ((FieldName)Enum.Parse(typeof(FieldName), "IsActive", true)).ToString().Dump();
    ((FieldName)Enum.Parse(typeof(FieldName), "TaskIsActive", true)).ToString().Dump();
}

public enum FieldName
{
    Name,
    TaskName = Name,
    IsActive,
    TaskIsActive = IsActive
}
TaskName
TaskName
IsActive
IsActive
    public enum SortBy
    {
        Ascending = 0,
        Descending = 1,
        Asc = 0,
        Desc = 1
    }