Getting the max value of an enum

C#Enums

C# Problem Overview


How do you get the max value of an enum?

C# Solutions


Solution 1 - C#

Enum.GetValues() seems to return the values in order, so you can do something like this:

// given this enum:
public enum Foo
{
    Fizz = 3, 
    Bar = 1,
    Bang = 2
}

// this gets Fizz
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Last();

Edit

For those not willing to read through the comments: You can also do it this way:

var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Max();

... which will work when some of your enum values are negative.

Solution 2 - C#

I agree with Matt's answer. If you need just min and max int values, then you can do it as follows.

Maximum:

Enum.GetValues(typeof(Foo)).Cast<int>().Max();

Minimum:

Enum.GetValues(typeof(Foo)).Cast<int>().Min();

Solution 3 - C#

According to Matt Hamilton's answer, I thought on creating an Extension method for it.

Since ValueType is not accepted as a generic type parameter constraint, I didn't find a better way to restrict T to Enum but the following.

Any ideas would be really appreciated.

PS. please ignore my VB implicitness, I love using VB in this way, that's the strength of VB and that's why I love VB.

Howeva, here it is:

C#:

static void Main(string[] args)
{
    MyEnum x = GetMaxValue<MyEnum>(); //In newer versions of C# (7.3+)
    MyEnum y = GetMaxValueOld<MyEnum>();  
}

public static TEnum GetMaxValue<TEnum>()
  where TEnum : Enum
{
     return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Max();
}

//When C# version is smaller than 7.3, use this:
public static TEnum GetMaxValueOld<TEnum>()
  where TEnum : IComparable, IConvertible, IFormattable
{
    Type type = typeof(TEnum);

    if (!type.IsSubclassOf(typeof(Enum)))
        throw new
            InvalidCastException
                ("Cannot cast '" + type.FullName + "' to System.Enum.");

    return (TEnum)Enum.ToObject(type, Enum.GetValues(type).Cast<int>().Last());
}



enum MyEnum
{
    ValueOne,
    ValueTwo
}

VB:

Public Function GetMaxValue _
    (Of TEnum As {IComparable, IConvertible, IFormattable})() As TEnum

    Dim type = GetType(TEnum)

    If Not type.IsSubclassOf(GetType([Enum])) Then _
        Throw New InvalidCastException _
            ("Cannot cast '" & type.FullName & "' to System.Enum.")

    Return [Enum].ToObject(type, [Enum].GetValues(type) _
                        .Cast(Of Integer).Last)
End Function

Solution 4 - C#

This is slightly nitpicky but the actual maximum value of any enum is Int32.MaxValue (assuming it's a enum derived from int). It's perfectly legal to cast any Int32 value to an any enum regardless of whether or not it actually declared a member with that value.

Legal:

enum SomeEnum
{
    Fizz = 42
}

public static void SomeFunc()
{
    SomeEnum e = (SomeEnum)5;
}

Solution 5 - C#

After tried another time, I got this extension method:

public static class EnumExtension
{
    public static int Max(this Enum enumType)
    {           
        return Enum.GetValues(enumType.GetType()).Cast<int>().Max();             
    }
}

class Program
{
    enum enum1 { one, two, second, third };
    enum enum2 { s1 = 10, s2 = 8, s3, s4 };
    enum enum3 { f1 = -1, f2 = 3, f3 = -3, f4 };

    static void Main(string[] args)
    {
        Console.WriteLine(enum1.one.Max());        
    }
}

Solution 6 - C#

Use the Last function could not get the max value. Use the "max" function could. Like:

 class Program
    {
        enum enum1 { one, two, second, third };
        enum enum2 { s1 = 10, s2 = 8, s3, s4 };
        enum enum3 { f1 = -1, f2 = 3, f3 = -3, f4 };

        static void Main(string[] args)
        {
            TestMaxEnumValue(typeof(enum1));
            TestMaxEnumValue(typeof(enum2));
            TestMaxEnumValue(typeof(enum3));
        }

        static void TestMaxEnumValue(Type enumType)
        {
            Enum.GetValues(enumType).Cast<Int32>().ToList().ForEach(item =>
                Console.WriteLine(item.ToString()));

            int maxValue = Enum.GetValues(enumType).Cast<int>().Max();     
            Console.WriteLine("The max value of {0} is {1}", enumType.Name, maxValue);
        }
    }

Solution 7 - C#

In agreement with Matthew J Sullivan, for C#:

   Enum.GetValues(typeof(MyEnum)).GetUpperBound(0);

I'm really not sure why anyone would want to use:

   Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Last();

...As word-for-word, semantically speaking, it doesn't seem to make as much sense? (always good to have different ways, but I don't see the benefit in the latter.)

Solution 8 - C#

There are methods for getting information about enumerated types under System.Enum.

So, in a VB.Net project in Visual Studio I can type "System.Enum." and the intellisense brings up all sorts of goodness.

One method in particular is System.Enum.GetValues(), which returns an array of the enumerated values. Once you've got the array, you should be able to do whatever is appropriate for your particular circumstances.

In my case, my enumerated values started at zero and skipped no numbers, so to get the max value for my enum I just need to know how many elements were in the array.

VB.Net code snippets:

'''''''

Enum MattType
  zerothValue         = 0
  firstValue          = 1
  secondValue         = 2
  thirdValue          = 3
End Enum

'''''''

Dim iMax      As Integer
      
iMax = System.Enum.GetValues(GetType(MattType)).GetUpperBound(0)

MessageBox.Show(iMax.ToString, "Max MattType Enum Value")

'''''''

Solution 9 - C#

I used the following when I needed the min and max values of my enum. I just set a min equal to the lowest value of the enumeration and a max equal to the highest value in the enumeration as enum values themselves.

public enum ChannelMessageTypes : byte
{
    Min                 = 0x80, // Or could be: Min = NoteOff
    NoteOff             = 0x80,
    NoteOn              = 0x90,
    PolyKeyPressure     = 0xA0,
    ControlChange       = 0xB0,
    ProgramChange       = 0xC0,
    ChannelAfterTouch   = 0xD0,
    PitchBend           = 0xE0,
    Max                 = 0xE0  // Or could be: Max = PitchBend
}

// I use it like this to check if a ... is a channel message.
if(... >= ChannelMessageTypes.Min || ... <= ChannelMessages.Max)
{
    Console.WriteLine("Channel message received!");
}

Solution 10 - C#

In F#, with a helper function to convert the enum to a sequence:

type Foo =
    | Fizz  = 3
    | Bang  = 2

// Helper function to convert enum to a sequence. This is also useful for iterating.
// stackoverflow.com/questions/972307/can-you-loop-through-all-enum-values-c
let ToSeq (a : 'A when 'A : enum<'B>) =
    Enum.GetValues(typeof<'A>).Cast<'B>()

// Get the max of Foo
let FooMax = ToSeq (Foo()) |> Seq.max   

Running it...

> type Foo = | Fizz = 3 | Bang = 2
> val ToSeq : 'A -> seq<'B> when 'A : enum<'B>
> val FooMax : Foo = Fizz

The when 'A : enum<'B> is not required by the compiler for the definition, but is required for any use of ToSeq, even by a valid enum type.

Solution 11 - C#

It is not usable in all circumstances, but I often define the max value myself:

enum Values {
  one,
  two,
  tree,
  End,
}

for (Values i = 0; i < Values.End; i++) {
  Console.WriteLine(i);
}

var random = new Random();
Console.WriteLine(random.Next((int)Values.End));

Of course this won't work when you use custom values in an enum, but often it can be an easy solution.

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
QuestionjdelatorView Question on Stackoverflow
Solution 1 - C#Matt HamiltonView Answer on Stackoverflow
Solution 2 - C#Karanvir KangView Answer on Stackoverflow
Solution 3 - C#Shimmy WeitzhandlerView Answer on Stackoverflow
Solution 4 - C#JaredParView Answer on Stackoverflow
Solution 5 - C#Eric FengView Answer on Stackoverflow
Solution 6 - C#Eric FengView Answer on Stackoverflow
Solution 7 - C#EngineerView Answer on Stackoverflow
Solution 8 - C#Matthew J SullivanView Answer on Stackoverflow
Solution 9 - C#XLarsView Answer on Stackoverflow
Solution 10 - C#Stephen HoskingView Answer on Stackoverflow
Solution 11 - C#yvan vander sandenView Answer on Stackoverflow