枚举类型变量,默认是否总是设置为第一个元素?
枚举类型中表示值为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
(如上所引用的文档所述,需要将其强制转换为给定的枚举类型)。
'\0'
或 default(char)
对应,否则仍然为 0。但是,由于 default(char)
是对应于字符代码 0 的 NUL 字符,因此这种情况高度不太可能发生。 - BoltClockDefaultValue
属性 - 类似于System.ComponentModel.DefaultValue(MyEnum.Blah)
- 会修改default(MyEnum)
的行为,但它仍然产生0。是否没有办法为枚举创建一个抽象,围绕其默认值? - Craig Silver我认为依赖枚举值的顺序并假设第一个始终是默认值是相当危险的。如果你担心保护默认值,这将是一个好的实践。
enum E
{
Foo = 0, Bar, Baz, Quux
}
否则,只需要不小心重构顺序,你就会得到一个完全不同的默认值。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
}
}