What is the default value for enum variable?
Asked Answered
M

3

344

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

Monongahela answered 11/2, 2011 at 9:57 Comment(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).Cristionna
C
525

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

Californium answered 11/2, 2011 at 9:58 Comment(4)
Thanks, and what about enums defined with char instead of int. e.g. enum Status { Active = 'A', Inactive='I'}Forejudge
@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.Californium
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?Pajamas
@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.Californium
R
14

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.

Removed answered 13/9, 2016 at 11:5 Comment(1)
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 :(Chishima
H
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
    }
}
Hepsibah answered 9/10, 2020 at 13:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.