335

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

kingsfoil
  • 3,795
  • 7
  • 32
  • 56
user496949
  • 83,087
  • 147
  • 309
  • 426
  • 1
    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 Mar 18 '16 at 00:25

3 Answers3

508

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).

BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • 2
    Thanks, and what about enums defined with char instead of int. e.g. enum Status { Active = 'A', Inactive='I'} – Fernando Torres Apr 24 '15 at 16:17
  • 4
    @Fernando Torres: Still 0, unless one of your enum values corresponds to `'\0'` or `default(char)`, which is highly unlikely since `default(char)` is the NUL character which corresponds to char code 0. – BoltClock Apr 24 '15 at 16:23
  • I (incorrectly?) assumed that using the `DefaultValue` attribute--something like `System.ComponentModel.DefaultValue(MyEnum.Blah)`--would modify the behaviour of `default(MyEnum)` but it still yields 0. Is there no way to create an abstraction for an `enum` around its default value? – Craig Silver Jan 17 '16 at 17:18
  • 2
    @Craig Silver: The DefaultValue attribute applies to properties - an enum is a type and as such, DefaultValue has no effect on the enum type as a whole. I suppose you could work around this with an extension method of sorts, but you're better off just checking for 0. – BoltClock Jan 17 '16 at 17:24
13

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.

user3154431
  • 308
  • 3
  • 8
  • 18
    Sorry you are wrong. I've assumed the same but if you put `Foo` after `Bar` both `Foo` and `Bar` will have value of 0 and `E.Foo == E.Bar` will return `true`. It's so stupid and counterintuitive but it's true :( – Pawcio Jul 10 '19 at 11:14
11

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
    }
}
Piero Álvarez
  • 300
  • 3
  • 7