C# 中奇怪的枚举名称解析

影响

考虑以下代码:

using System;

namespace Test
{
    enum Foo
    {
        A = 1,
        B = 1,
        C = 1
    }
    
    public static class Program
    {
        public static void Main()
        {
            Console.WriteLine("{0}, {1}, {2}", Foo.A, Foo.B, Foo.C);
        }
    }
}

明知枚举是引擎盖下只是整数,我希望它是两种A, A, AC, C, C但令人惊讶的是,它打印出来了B, B, B这种行为在 .NET Framework、.NET Core 3.x 和 .NET 5 中似乎是一致的。

它为什么选择B

马修·沃森

根据 Enum.GetName() 的文档,它是未定义的:

如果多个枚举成员具有相同的基础值,则 GetName 方法保证它将返回这些枚举成员之一的名称。但是,它不保证总是返回同一个枚举成员的名称。

所以在这方面它可以为所欲为。

至于为什么B在您的示例中返回,我们可以检查的实现GetEnumName()

public virtual string GetEnumName(object value)
{
    if (value == null)
        throw new ArgumentNullException("value");

    if (!IsEnum)
        throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnum"), "enumType");
    Contract.EndContractBlock();

    Type valueType = value.GetType();

    if (!(valueType.IsEnum || Type.IsIntegerType(valueType)))
        throw new ArgumentException(Environment.GetResourceString("Arg_MustBeEnumBaseTypeOrEnum"), "value");

    Array values = GetEnumRawConstantValues();
    int index = BinarySearch(values, value);

    if (index >= 0)
    {
        string[] names = GetEnumNames();
        return names[index];
    }

    return null;
}

啊哈!一切都解释了。为了使查找更快,他们使用了二进制搜索。开始搜索时,二分搜索查找的第一个位置在哪里?没错 - 它从列表的一半开始。这就是为什么它要找到第B一个 - 在列表排序后,B中间的。

(请注意,列表按枚举值排序,而不是枚举名称,因此对于您的情况,列表已经排序,因为所有值都相同。)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章