278
votes

An enum variable, anyone know if it is always defaulting to the first element?

3
One consideration for the use case where a default enum is desired is to use a nullable variable. When a null is received, it can be translated in the correct part of the code into the default, and this default doesn't have to be known in the rest of the code (that just passes along a null).ErikE

3 Answers

426
votes

It is whatever member of the enumeration represents the value 0. Specifically, from the documentation:

The default value of an enum E is the value produced by the expression (E)0.

As an example, take the following enum:

enum E
{
    Foo, Bar, Baz, Quux
}

Without overriding the default values, printing default(E) returns Foo since it's the first-occurring element.

However, it is not always the case that 0 of an enum is represented by the first member. For example, if you do this:

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

Printing default(F) will give you Quux, not Foo.

If none of the elements in an enum G correspond to 0:

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

default(G) returns literally 0, although its type remains as G (as quoted by the docs above, a cast to the given enum type).

11
votes

I think it's quite dangerous to rely on the order of the values in a enum and to assume that the first is always the default. This would be good practice if you are concerned about protecting the default value.

enum E
{
    Foo = 0, Bar, Baz, Quux
}

Otherwise, all it takes is a careless refactor of the order and you've got a completely different default.

1
votes

You can use this snippet :-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);
    }
}

Example:

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
    }
}