我刚刚发现了一个微妙的错误,我有一个枚举,两个名字无意中共享相同的数值(在这种情况下,红色= 10和深红色= 10)。我有点意外,这不是语法错误。
public enum Colour
{
Red=10,
Blue=11,
Green=12,
Crimson=10
}
// Debug.Write(Colour.Red==Colour.Crimson) outputs True
为什么这种行为可能有用或者认为它应该是语法错误,是否有任何现实世界的原因?
答案 0 :(得分:38)
public enum Colour
{
Red=10,
Rouge=10,
Blue=11,
Bleu=11,
Green=12,
Vert=12,
Black=13,
Noir=13
}
答案 1 :(得分:24)
小心!如果您的enum
包含多个具有相同值的元素,则在使用Enum.Parse()
时可能会出现意外结果。这样做会随意返回具有请求值的第一个元素。例如,如果您有enum Car { Ford = 1, Chevy = 1, Mazda = 1}
,则(Car)Enum.Parse(typeof(Car), "1")
将返回Car.Ford
。虽然这可能有用(我不确定为什么会这样),但在大多数情况下,它可能会让人感到困惑(特别是对于维护代码的工程师),或者在出现问题时容易被忽视。
答案 2 :(得分:19)
我看到此功能有时用于“默认”值:
public enum Scope
{
Transient,
Singleton,
Default=Transient
}
但要注意,这只是你的枚举用户的糖。仅仅因为它被称为默认,它并不意味着它是初始值。
答案 3 :(得分:10)
枚举与constans一样使用,你肯定可以有两个具有相同值的常量,它们在同一个地方使用。由于第三方API,它可能是这样,因为后向兼容性仅仅是因为业务规则。
答案 4 :(得分:7)
多个枚举成员可以共享相同的关联值。例子
enum Color
{
Red,
Green,
Blue,
Max = Blue
}
显示一个枚举,其中两个枚举成员 - 蓝色和最大 - 具有相同的关联值。
在这种情况下,您可以检查MyColor == Color.Max,这在某些情况下会很有用。
答案 5 :(得分:4)
枚举是常量变量的枚举,你可以有两个具有相同值的项,我认为没有理由是语法错误,但是,这会导致此代码中的编译错误
switch(c)
{
Colour.Red:
break;
Colour.Crimson:
break;
...
}
答案 6 :(得分:3)
这不是语法错误。所有enum
都以强类型的方式枚举一系列常量。
因此,如果开发人员输入错误(如在您的示例中),就CLR而言,这是一个非常有效的案例。 CLR假设开发人员知道他在做什么,以及他选择这样做的原因。
至于现实世界的情况,我无法想出任何关于时刻的事情,但我仍然确定在某些情况下它可能会有所帮助。
答案 7 :(得分:2)
当然有,虽然它可能不太常见。如果存在一个通常以两个不同名称知道的实体/值,那么这是一个很好的理由。
您提出的情景可能就是这种情况。直接来自BCL的更好的是System.Windows.Forms.MessageBoxIcon
枚举; Stop
,Error
和Hand
成员都具有相同的描述且确实具有相同的值。 Asterisk
和Information
也是相同的,如评论所示:
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.
希望这可以让你对适当的场景有所了解(你自己可能是一个场景)。
答案 8 :(得分:1)
我目前正在开发一个项目,这实际上是一个有用的功能。
public enum State
{
NotTransmitted = 0,
Deleted = 0,
Transmitted = 1,
Deactivated = 1,
Activated = 2
}
状态 NotTransmitted 和 Deleted 在编程上是相同的,对于实际情况的软件来说无关紧要。在这两种情况下,软件都必须 f.e.将此项目发送给接收方。
话虽如此,对于程序员来说,在删除之后将状态设置为“已删除”比将其设置为“未传输”要直观得多。传输后设置为“已传输”也是如此,将其设置为“已停用”。
简而言之,它增强了代码的可读性。
答案 9 :(得分:1)
此示例将说明这有用的原因。当您在致力于公共使用的公共图书馆工作时,以不同方式命名相同的内容可能会有用。
public enum GestureType
{
Touch = 1,
Tap = 1,
DoubleTouch = 2,
DoubleTap = 2,
Swipe = 3,
Slide = 3,
...
}
当某些情况下不同的词语具有相同的含义时,它们就有意义。在解析时,它总是在这种情况下返回良好的值。
答案 10 :(得分:1)
这是有效的,允许用不同的名称引用相同的值。 要注意这一点很有效。如果要从int / string转换为enum或格式化字符串,则可能会得到不一致的结果。
例如:
public enum Colour
{
Red=10,
Blue=11,
Green=12,
Crimson=10
}
Colour myColor = Colour.Crimson;
Console.WriteLine("Crimson is {0}", myColor.ToString());
输出:
Crimson is Red
答案 11 :(得分:1)
答案 12 :(得分:1)
使用命名值而不是实际值是root。假设您有相同的法语,英语等。这是我的枚举的根源。
答案 13 :(得分:1)
没关系。您可以有两个与API用户的观点不同的值,但在功能上可以视为相同的值。
答案 14 :(得分:0)
我认为重复使用相同数字有很多用途。举一个新的例子,假设你有一个排名系统,可以确保特定类(父)的对象在依赖它的其他类(子级)之前创建,你可能有一些孩子在同一个级别'并且首先创建哪一个并不重要。在下面的示例中,将首先创建Parent,然后创建Child 1,2或3,然后最后创建Child4。如果将其视为树形图,则具有相同编号的任何项目都将是“兄弟姐妹”。
public enum ObjectRanks
{
Parent = 0,
Child1 = 1,
Child2 = 1,
Child3 = 1,
Child4 = 2
}
虽然我可以看到你的观点,但这可能很容易被误解。在这种情况下,如果visual studio有一个选项来启用警告可以让它编译,但如果两次使用相同的数字会发出警告,那将会很方便。
答案 15 :(得分:0)
我认为它对于字段映射很有用,例如(在LinqPad中):
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
}
目标是使用较短的名称,但是Parse或TryParse的结果不一致,并且此代码输出:
TaskName
TaskName
IsActive
IsActive
答案 16 :(得分:0)
public enum SortBy
{
Ascending = 0,
Descending = 1,
Asc = 0,
Desc = 1
}
这就是为什么该解决方案对我有用的原因
答案 17 :(得分:0)
我在.net TWAIN包装器中看到了同样的东西 - 它允许所有TWAIN消息代码存储在一个大的枚举中,但它确实让事情有点混乱。