【问题标题】:Inconsistent Enum Casting Results in C#C# 中不一致的枚举类型转换结果
【发布时间】:2016-01-11 07:03:56
【问题描述】:

我最近重新审视了 C# 的一些奇怪行为,这些行为与将整数转换为现有枚举相关,其中一些枚举整数值是显式分配的,而一些是按顺序分配的。使用 LinqPad 4,我构建了以下枚举:

public enum Hurf {
    Foo,
    Bar,
    Derp,
    Duh = 2,
    Lerp,
    Mur,
    Dur = 3
}

在 C# 程序模式下使用以下 Main 块体,我执行以下转换:

Console.WriteLine((Hurf)2);
Console.WriteLine((int)Hurf.Derp);

Console.WriteLine((Hurf)3);
Console.WriteLine((int)Hurf.Lerp);

这会产生以下输出:

Derp
2
Dur
3

奇怪的是,在第一次演员表中,由于有两个整数值为 2 的项目,它默认为第一个项目,即“Derp”。使用相同的逻辑,我使用整数值 3 执行另一个强制转换,这一次它导致 SECOND 值 3,即“Dur”。

我决定在“Dur”正下方的枚举底部添加另一个项目作为“测试”并将其设置为0。

public enum Hurf {
    Foo,
    Bar,
    Derp,
    Duh = 2,
    Lerp,
    Mur,
    Dur = 3,
    Test = 0
}

这不会改变第一次转换的行为,但现在第二次转换的结果是“Lerp”,这与它转换为枚举中设置的第一个值 3 是一致的。

Duh
2
Lerp
3

出于显而易见的原因,我不会一开始就依赖这种类型的转换,但很高兴知道为什么会存在这种行为并且会受到枚举列表底部的任意手动分配的影响。 (此外,将“Test”设置为大于 3 的值会导致返回原始行为。)

【问题讨论】:

    标签: c# casting enums


    【解决方案1】:

    问题不在于转换,而是转换为字符串表示。 LerpDur 是相同的值 - 你无法区分它们。

    确实,如果你直接在他们身上调用ToString(),就像这样:

    Console.WriteLine(Hurf.Lerp.ToString());
    Console.WriteLine(Hurf.Dur.ToString());
    

    ...您应该期望看到两次相同的输出。它只是没有明确定义你会得到哪个输出。

    documentation for Enum.ToString() 明确声明:

    如果多个枚举成员具有相同的基础值,并且您尝试根据其基础值检索枚举成员名称的字符串表示形式,则您的代码不应对该方法将返回哪个名称做出任何假设。

    【讨论】:

    • 感谢您的回复。所以你说的是从整数到枚举类型的转换正在执行一个 ToString ,它会产生不稳定的行为。我仍然觉得有趣的是,对其他成员的任意更改会导致顺序更改以确定选择哪个项目进行转换(有时是第一个,有时是第二个)。
    • @IanJ.:不,一点也不。 您正在(隐式地)通过调用Console.WriteLine 并传入枚举类型的值来调用ToString()。转换根本没有“古怪”的行为 - 转换只是产生一个 Hurf 值,其基础值与原始整数相同。
    • 我认为我们在这里仍然专注于错误的事情,这就是 ToString 如此不一致的原因。
    • @IanJ:这是不一致的,因为在模棱两可的情况下没有“正确”的答案,它是一个实现细节——就像字典成员的迭代顺序一样。 重要的是区分枚举/整数转换和枚举/字符串转换。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-21
    • 2023-02-21
    • 1970-01-01
    • 2017-10-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多