枚举变量的默认值是什么?

336

枚举类型变量,默认是否总是设置为第一个元素?


1
对于需要默认枚举的用例,考虑使用可空变量。当接收到 null 时,它可以在代码的正确部分转换为默认值,并且这个默认值不必在其余代码中被知道(只需传递一个 null)。 - ErikE
3个回答

513

枚举类型中表示值为0的成员。具体来说,来自于文档

enum E 的默认值是表达式(E)0产生的值。

例如,考虑以下枚举:

enum E
{
    Foo, Bar, Baz, Quux
}

不覆盖默认值的情况下,打印default(E)会返回Foo,因为它是第一个出现的元素。

然而,并非总是如此,枚举类型中的0并不总是由第一个成员表示。例如,如果您这样做:

enum F
{
    // Give each element a custom value
    Foo = 1, Bar = 2, Baz = 3, Quux = 0
}

打印default(F)会输出Quux而不是Foo

如果枚举类型G中没有元素对应于0

enum G
{
    Foo = 1, Bar = 2, Baz = 3, Quux = 4
}

default(G)返回的字面值为0,尽管其类型仍为G(如上所引用的文档所述,需要将其强制转换为给定的枚举类型)。


2
谢谢,那么使用char而不是int定义的枚举类型怎么办呢? 例如:enum Status { Active = 'A', Inactive='I'} - Fernando Torres
4
@Fernando Torres:除非你的枚举值与 '\0'default(char) 对应,否则仍然为 0。但是,由于 default(char) 是对应于字符代码 0 的 NUL 字符,因此这种情况高度不太可能发生。 - BoltClock
我(错误地?)假设使用DefaultValue属性 - 类似于System.ComponentModel.DefaultValue(MyEnum.Blah) - 会修改default(MyEnum)的行为,但它仍然产生0。是否没有办法为枚举创建一个抽象,围绕其默认值? - Craig Silver
2
@Craig Silver: DefaultValue属性适用于属性 - 枚举是一种类型,因此DefaultValue对枚举类型整体没有影响。我想你可以通过某种扩展方法来解决这个问题,但最好还是检查0的值。 - BoltClock

13

我认为依赖枚举值的顺序并假设第一个始终是默认值是相当危险的。如果你担心保护默认值,这将是一个好的实践。

enum E
{
    Foo = 0, Bar, Baz, Quux
}
否则,只需要不小心重构顺序,你就会得到一个完全不同的默认值。

19
抱歉,你错了。我也曾经做出过同样的假设,但如果你在“Bar”之后放置“Foo”,则“Foo”和“Bar”都将具有值0,并且“E.Foo == E.Bar”将返回“true”。这很愚蠢和违反直觉,但却是事实。 :( - Pawcio

11
你可以使用这段代码 :-D
using System;
using System.Reflection;

public static class EnumUtils
{
    public static T GetDefaultValue<T>()
        where T : struct, Enum
    {
        return (T)GetDefaultValue(typeof(T));
    }

    public static object GetDefaultValue(Type enumType)
    {
        var attribute = enumType.GetCustomAttribute<DefaultValueAttribute>(inherit: false);
        if (attribute != null)
            return attribute.Value;

        var innerType = enumType.GetEnumUnderlyingType();
        var zero = Activator.CreateInstance(innerType);
        if (enumType.IsEnumDefined(zero))
            return zero;

        var values = enumType.GetEnumValues();
        return values.GetValue(0);
    }
}

例子:

using System;

public enum Enum1
{
    Foo,
    Bar,
    Baz,
    Quux
}
public enum Enum2
{
    Foo  = 1,
    Bar  = 2,
    Baz  = 3,
    Quux = 0
}
public enum Enum3
{
    Foo  = 1,
    Bar  = 2,
    Baz  = 3,
    Quux = 4
}
[DefaultValue(Enum4.Bar)]
public enum Enum4
{
    Foo  = 1,
    Bar  = 2,
    Baz  = 3,
    Quux = 4
}

public static class Program 
{
    public static void Main() 
    {
        var defaultValue1 = EnumUtils.GetDefaultValue<Enum1>();
        Console.WriteLine(defaultValue1); // Foo

        var defaultValue2 = EnumUtils.GetDefaultValue<Enum2>();
        Console.WriteLine(defaultValue2); // Quux

        var defaultValue3 = EnumUtils.GetDefaultValue<Enum3>();
        Console.WriteLine(defaultValue3); // Foo

        var defaultValue4 = EnumUtils.GetDefaultValue<Enum4>();
        Console.WriteLine(defaultValue4); // Bar
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接