【发布时间】:2021-10-07 17:46:24
【问题描述】:
我正在使用枚举循环引用将一些现有枚举归结为更少的值。 它适用于我的问题,因为它适用于过渡时期,在历史中确实会出现旧的枚举值,但不会创建具有过时值的新条目。
我不是在寻找替代方法,但我偶然发现了这个奇怪的问题,其中枚举的顺序会以意想不到的方式影响序列化值。
我有这个枚举:
public enum CivilStatusEnum
{
None = 0,
Married = 1,
Cohabiting = Married,
Alone = 3,
DivorcedOrSeparated = Alone,
WidowOrWidower = Alone,
}
我指定了“DivorcedOrSeparated”= 单独 (3)。现在,当我将枚举转换为字符串时,我得到值“DivorcedOrSeparated”。
Console.PrintLine(CivilStatusEnum.Alone.ToString());
输出:
DivorcedOrSeparated
我有一个示例代码,其中包含测试及其预期结果。如您所见,测试失败。但是如果我改变枚举的顺序,测试就会解析。
[Theory]
[InlineData(CivilStatusEnum.Alone, "Alone")]
[InlineData(CivilStatusEnum.DivorcedOrSeparated, "Alone")]
[InlineData(CivilStatusEnum.WidowOrWidower, "Alone")]
[InlineData(CivilStatusEnum.None, "None")]
[InlineData(CivilStatusEnum.Married, "Married")]
[InlineData(CivilStatusEnum.Cohabiting, "Married")]
public void Test(CivilStatusEnum input, string expected)
{
var text = input.ToString();
text.Should().Be(expected);
}
我似乎无法找到一个合理的解释来解释为什么顺序对 tostring 和 serilization 很重要。
这是 .NET 5 中的错误,还是我遗漏了什么? 如果这种行为是故意的,它如何确定哪个枚举名称将是 tostring 的输出?
谢谢你:)
【问题讨论】:
-
存储的不是枚举文本(“Alone”),而是它的值(3)。那么你的意思是哪个值 3 ?独自一人、离婚或分居,还是寡妇或鳏夫?
-
附带说明:长期以来,我也将枚举视为“可以从中选择一个的文本值集”。但归根结底,枚举只是整数数据类型的一个很好的包装器。而且您的代码应该依赖于该底层数据类型,而不是它们的视觉表示。例如,如果您将整数转换为枚举类型。即使实际的整数可能甚至不是有效的变体,结果也会看起来像枚举变体之一。枚举只是不知道如何处理这个问题。相信枚举文本表示可能会产生很大的误导。
-
我知道枚举是值是 int 而不是字符串。但是我们谈论的是一个具有公共 API 和大量需要可用的历史数据的现有系统,所以我不能不付出很大的努力就改变方法。我只是想知道在调用 ToString() 时它如何确定要返回的字符串。