具有重复值的枚举的GetName

时间:2012-03-17 23:09:26

标签: c#

如果我在C#枚举中有重复值,请说

enum MyE {
  value1 = 1,
  value2 = 2,
  valued = 1
}

以下字符串的值应该是什么?

MyE N = (MyE)1;
string V1 = N.ToString();
string V2 = GetName(MyE, 1);

V1和V2必须包含相同的值吗? 这些价值应该是什么?

我没有在MSDN中找到任何内容,或者在这里有关于重复的枚举的“解除引用”,请指出我的链接,如果我错过了。

5 个答案:

答案 0 :(得分:15)

实验表明:

  

V1 =“value1”

  

V2 =“value1”

但是,这不能保证。 MSDN page on Enum.GetName州:

  

如果多个枚举成员具有相同的基础值,则GetName方法保证它将返回其中一个枚举成员的名称。但是,它不保证它始终返回相同枚举成员的名称。因此,当多个枚举成员具有相同的值时,您的应用程序代码永远不应该依赖于返回特定成员名称的方法。

答案 1 :(得分:2)

Enum.GetName方法文档(http://msdn.microsoft.com/en-us/library/system.enum.getname.aspx)的“备注”部分中,它说:

  

如果多个枚举成员具有相同的基础值,则GetName方法保证它将返回其中一个枚举成员的名称。但是,它不保证它始终返回相同枚举成员的名称。因此,当多个枚举成员具有相同的值时,您的应用程序代码永远不应该依赖于返回特定成员名称的方法。

我运行测试以查看实验会发生什么,并且它总是返回定义的第一个值(在您的示例中为value1),但根据上面的官方文档,您不能依赖 (参见@ gluk47的评论,表明野外的不同行为)。

答案 2 :(得分:1)

我不同意其他答案声明

  

......这不是保证......

     

...你不能依赖 ......

以及msdn声明:

  

...您的应用程序代码永远不应该依赖于返回特定成员名称的方法......

故事

我的软件中有一个枚举

enum Blabla { A = 0, B = 1, C = 2, D = 3 }

某些时候A值更改为AA,后来AA更改为AAA。为了保持向后兼容,我不得不这样做

enum Blabla { A = 0, AA = 0, AAA = 0, B = 1, C = 2, D = 3 }

这允许将旧的枚举值(由旧版软件制作)反序列化为AAA

然后有一个报告打印Blabla设置值。在某些时候,每个使用新版本的客户都会开始告诉我他们看到AAAAA而不是AA。所有人都看到A(没有人报告AAA)。

我做了什么?我只是更改顺序(直到结果为enum Blabla { AAA = 0, A = 0, AA = 0, ...}

Blabla.AAA

并进行了测试,以确保将AAA输出为Enum.ToString()。问题解决了吗?

证据

查看Enum.GetName()(或Array.BinarySearch())的来源,它使用GetEnumName(),它调用enum来排序值的数组以查找值的索引。

二元搜索的结果是 deterministic :为其提供相同的参数将返回相同的结果

所以:

  • 如果你不改变枚举,那么结果将是相同的。
  • 可以通过实验找到结果(或者通过了解binary search如何工作以及如何处理枚举)。
  • 确定结果没有简单的规则(例如,您不能说"它总是返回第一个定义的值")。
  • 不太可能Enum.ToString()格式将被更改(例如,定义顺序和值列表顺序不同)或else将被更改,但它可能会发生,因此请确保你对依赖返回值的情况进行测试。

答案 3 :(得分:0)

好吧,因为无法保证订单和过时的属性似乎对Enum方法没有影响,我通常会建议使用字符串属性进行序列化,并使用自定义代码来处理过时的值。

这样,主Enum没有重复,只包含当前值。

根据序列化框架,您可以将字符串属性标记为可序列化但过时,并且序列化将忽略代码中使用的实际属性。

要处理字符串属性设置器中的过时值,可以使用[Obsolete] enum或switch语句。通常,我可能会使用前者,如果我有很多过时的值来处理,后者如果我只有几个值可以处理。

将代码放在辅助类或扩展方法中也是有意义的,特别是如果从一堆地方加载或存储该值。

虽然我在生产代码中没有尝试过多,但我想知道使用struct代替enum来控制更多内容是否更好......但我认为需要许多样板代码不能轻易通用。

答案 4 :(得分:0)

虽然这对党来说可能有点晚了,但这可能不是一个好主意,但是,在我不得不使用重复枚举的情况下,我确实找到了一个解决方法,那就是使用这里的问题; Get String Name from Enum in C#

var name = nameof(DeclaredEnum.EnumName);

结果:

EnumName

您可以阅读更多Here,了解其实际工作原理。