C#中的枚举强制转换结果不一致

本文关键字:转换 结果 不一致 枚举 | 更新日期: 2023-09-27 18:29:49

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

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

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

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执行另一个强制转换,这一次它产生了3的第二个值,即"Dur"。

我决定在"Dur"正下方的枚举底部添加另一个项作为"Test",并将其设置为0。

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

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

Duh
2
Lerp
3

出于显而易见的原因,我一开始不会依赖这种类型的强制转换,但如果能知道为什么会存在这种行为,并受到枚举列表底部任意手动赋值的影响,那就太好了。(此外,将"Test"设置为高于3的值会导致返回原始行为。)

C#中的枚举强制转换结果不一致

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

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

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

您应该期望看到两次相同的输出。它只是没有定义好,您将得到哪个输出。

Enum.ToString()的文档明确指出:

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