Choosing the default value of an Enum type without having to change values

C#.NetEnums

C# Problem Overview


In C#, is it possible to decorate an Enum type with an attribute or do something else to specify what the default value should be, without having the change the values? The numbers required might be set in stone for whatever reason, and it'd be handy to still have control over the default.

enum Orientation
{
    None = -1,
    North = 0,
    East = 1,
    South = 2,
    West = 3
}

Orientation o; // Is 'North' by default.

C# Solutions


Solution 1 - C#

The default for an enum (in fact, any value type) is 0 -- even if that is not a valid value for that enum. It cannot be changed.

Solution 2 - C#

The default value of any enum is zero. So if you want to set one enumerator to be the default value, then set that one to zero and all other enumerators to non-zero (the first enumerator to have the value zero will be the default value for that enum if there are several enumerators with the value zero).

enum Orientation
{
    None = 0, //default value since it has the value '0'
    North = 1,
    East = 2,
    South = 3,
    West = 4
}

Orientation o; // initialized to 'None'

If your enumerators don't need explicit values, then just make sure the first enumerator is the one you want to be the default enumerator since "By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1." (C# reference)

enum Orientation
{
    None, //default value since it is the first enumerator
    North,
    East,
    South,
    West
}

Orientation o; // initialized to 'None'

Solution 3 - C#

If zero doesn't work as the proper default value, you can use the component model to define a workaround for the enum:

[DefaultValue(None)]
public enum Orientation
{
     None = -1,
     North = 0,
     East = 1,
     South = 2,
     West = 3
 }

public static class Utilities
{
    public static TEnum GetDefaultValue<TEnum>() where TEnum : struct
    {
        Type t = typeof(TEnum);
        DefaultValueAttribute[] attributes = (DefaultValueAttribute[])t.GetCustomAttributes(typeof(DefaultValueAttribute), false);
        if (attributes != null &&
            attributes.Length > 0)
        {
            return (TEnum)attributes[0].Value;
        }
        else
        {
            return default(TEnum);
        }
    }
}

and then you can call:

Orientation o = Utilities.GetDefaultValue<Orientation>();
System.Diagnostics.Debug.Print(o.ToString());

Note: you will need to include the following line at the top of the file:

using System.ComponentModel;

This does not change the actual C# language default value of the enum, but gives a way to indicate (and get) the desired default value.

Solution 4 - C#

An enum's default is whatever enumeration equates to zero. I don't believe this is changeable by attribute or other means.

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

Solution 5 - C#

One more way that might be helpful - to use some kind of "alias". For example:

public enum Status
{
    New = 10,
    Old = 20,
    Actual = 30,

    // Use Status.Default to specify default status in your code. 
    Default = New 
}

Solution 6 - C#

You can't, but if you want, you can do some trick. :)

    public struct Orientation
    {
        ...
        public static Orientation None = -1;
        public static Orientation North = 0;
        public static Orientation East = 1;
        public static Orientation South = 2;
        public static Orientation West = 3;
    }

usage of this struct as simple enum.
where you can create p.a == Orientation.East (or any value that you want) by default
to use the trick itself, you need to convert from int by code.
there the implementation:

        #region ConvertingToEnum
        private int val;
        static Dictionary<int, string> dict = null;

        public Orientation(int val)
        {
            this.val = val;
        }

        public static implicit operator Orientation(int value)
        {
            return new Orientation(value - 1);
        }

        public static bool operator ==(Orientation a, Orientation b)
        {
            return a.val == b.val;
        }

        public static bool operator !=(Orientation a, Orientation b)
        {
            return a.val != b.val;
        }

        public override string ToString()
        {
            if (dict == null)
                InitializeDict();
            if (dict.ContainsKey(val))
                return dict[val];
            return val.ToString();
        }

        private void InitializeDict()
        {
            dict = new Dictionary<int, string>();
            foreach (var fields in GetType().GetFields(BindingFlags.Public | BindingFlags.Static))
            {
                dict.Add(((Orientation)fields.GetValue(null)).val, fields.Name);
            }
        } 
        #endregion

Solution 7 - C#

Actually an enum's default is the first element in the enum whose value is 0.

So for example:

public enum Animals
{
    Cat,
    Dog,
    Pony = 0,
}
//its value will actually be Cat not Pony unless you assign a non zero value to Cat.
Animals animal;

Solution 8 - C#

The default value of enum is the enummember equal to 0 or the first element(if value is not specified) ... But i have faced critical problems using enum in my projects and overcome by doing something below ... How ever my need was related to class level ...

    class CDDtype
    {
        public int Id { get; set; }
        public DDType DDType { get; set; }

        public CDDtype()
        {
            DDType = DDType.None;
        }
    }    

    
    [DefaultValue(None)]
    public enum DDType
    {       
        None = -1,       
        ON = 0,       
        FC = 1,       
        NC = 2,       
        CC = 3
    }

and get expected result

    CDDtype d1= new CDDtype();
    CDDtype d2 = new CDDtype { Id = 50 };

    Console.Write(d1.DDType);//None
    Console.Write(d2.DDType);//None

Now what if value is coming from DB .... Ok in this scenario... pass value in below function and it will convertthe value to enum ...below function handled various scenario and it's generic... and believe me it is very fast ..... :)

    public static T ToEnum<T>(this object value)
    {
        //Checking value is null or DBNull
        if (!value.IsNull())
        {
            return (T)Enum.Parse(typeof(T), value.ToStringX());
        }

        //Returanable object
        object ValueToReturn = null;

        //First checking whether any 'DefaultValueAttribute' is present or not
        var DefaultAtt = (from a in typeof(T).CustomAttributes
                          where a.AttributeType == typeof(DefaultValueAttribute)
                          select a).FirstOrNull();

        //If DefaultAttributeValue is present
        if ((!DefaultAtt.IsNull()) && (DefaultAtt.ConstructorArguments.Count == 1))
        {
            ValueToReturn = DefaultAtt.ConstructorArguments[0].Value;
        }

        //If still no value found
        if (ValueToReturn.IsNull())
        {
            //Trying to get the very first property of that enum
            Array Values = Enum.GetValues(typeof(T));

            //getting very first member of this enum
            if (Values.Length > 0)
            {
                ValueToReturn = Values.GetValue(0);
            }
        }

        //If any result found
        if (!ValueToReturn.IsNull())
        {
            return (T)Enum.Parse(typeof(T), ValueToReturn.ToStringX());
        }

        return default(T);
    }

Solution 9 - C#

The default value for an enumeration type is 0:

  • "By default, the first enumerator has the value 0, and the value of each successive enumerator is increased by 1."

  • "The value type enum has the value produced by the expression (E)0, where E is the enum identifier."

You can check the documentation for C# enum here, and the documentation for C# default values table here.

Solution 10 - C#

If you define the Default enum as the enum with the smallest value you can use this:

public enum MyEnum { His = -1, Hers = -2, Mine = -4, Theirs = -3 }

var firstEnum = ((MyEnum[])Enum.GetValues(typeof(MyEnum)))[0];

firstEnum == Mine.

This doesn't assume that the enum has a zero value.

Solution 11 - C#

enum Orientations
{
    None, North, East, South, West
}
private Orientations? _orientation { get; set; }

public Orientations? Orientation
{
    get
    {
        return _orientation ?? Orientations.None;
    }
    set
    {
        _orientation = value;
    }
}

If you set the property to null will return Orientations.None on get. The property _orientation is null by default.

Solution 12 - C#

The default is the first one in the definition. For example:

public enum MyEnum{His,Hers,Mine,Theirs}

Enum.GetValues(typeOf(MyEnum)).GetValue(0);

This will return His

Solution 13 - C#

Don't rely on the enum value in this case. Let None be 0 as a default.

// Remove all the values from the enum
enum Orientation
{
    None, // = 0 Putting None as the first enum value will make it the default
    North, // = 1
    East, // = 2
    South, // = 3
    West // = 4
}

Then use a method to get the Magic Number. You can introduce an Extension Method and use it like:

// Extension Methods are added by adding a using to the namespace
using ProjectName.Extensions;

Orientation.North.ToMagicNumber();

And here is the code:

namespace ProjectName.Extensions
{
    public static class OrientationExtensions 
    {
        public static int ToMagicNumber(this Orientation orientation) => oritentation switch
        {
            case None  => -1,
            case North => 0,
            case East  => 1,
            case South => 2,
            case West  => 3,
            _          => throw new ArgumentOutOfRangeException(nameof(orientation), $"Not expected orientation value: {orientation}")
        };
    }
}

Solution 14 - C#

[DefaultValue(None)]
public enum Orientation
{
    None = -1,
    North = 0,
    East = 1,
    South = 2,
    West = 3
}

Then in the code you can use

public Orientation GetDefaultOrientation()
{
   return default(Orientation);
} 

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionxyzView Question on Stackoverflow
Solution 1 - C#James CurranView Answer on Stackoverflow
Solution 2 - C#user65199View Answer on Stackoverflow
Solution 3 - C#DavidView Answer on Stackoverflow
Solution 4 - C#JoeView Answer on Stackoverflow
Solution 5 - C#Dmitry PavlovView Answer on Stackoverflow
Solution 6 - C#AvramView Answer on Stackoverflow
Solution 7 - C#CianView Answer on Stackoverflow
Solution 8 - C#MoumitView Answer on Stackoverflow
Solution 9 - C#acoelhosantosView Answer on Stackoverflow
Solution 10 - C#Tal SegalView Answer on Stackoverflow
Solution 11 - C#Faruk A FeresView Answer on Stackoverflow
Solution 12 - C#Tony HopkinsonView Answer on Stackoverflow
Solution 13 - C#RedwolfView Answer on Stackoverflow
Solution 14 - C#Ruslan UrbanView Answer on Stackoverflow