How do you get the max value of an enum?
-
1Possible duplicate of [Finding the Highest Value in an Enumeration](http://stackoverflow.com/questions/1747212/finding-the-highest-value-in-an-enumeration) – Ian Goldby Sep 15 '16 at 10:48
-
1I would think that the compiler could handle this, rather than using a Reflection call. An answer that used a compile-time method for this information would receive my up-vote. – palswim Jul 20 '17 at 21:08
11 Answers
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.

- 200,371
- 61
- 386
- 320
-
5nice. taking advantage of: "The elements of the array are sorted by the binary values of the enumeration constants." from http://msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx – TheSoftwareJedi Oct 15 '08 at 01:10
-
2I was smacking my head, thinking this was really trival but an elegant solution was given. Also if you want to get the enum value use Convert.ToInt32() afterwards. This is for the google results. – jdelator Oct 15 '08 at 01:15
-
If they are sorted by the binary representations, what happens to enum values that have a negative value? Negative values in binary actually have the highest order bit as a 1, as they are usually represented using 2's compliment, meaning the number that would end up at the end of the array is -1. – Kibbee Oct 15 '08 at 01:19
-
61If you're going to use LINQ, why not use Max(), which is much clearer, and doesn't rely on "seems to"? – Marc Gravell Oct 15 '08 at 05:51
-
Max() would work too. Given that the link above proves my assumption, though, I'd say Last() would perform better since it doesn't need to visit each item to see which is the maximum. – Matt Hamilton Oct 15 '08 at 06:55
-
3It performs better, but only if the values of the enum aren't negative, which they could be. – ICR Oct 15 '08 at 13:12
-
4I vote for Max() too. The Last() would fail if enum aren't negative, see [here](http://connect.microsoft.com/VisualStudio/feedback/details/98147/enum-getvalues) – AZ. Feb 15 '11 at 00:57
-
@AZ., [more correct link](//web-beta.archive.org/web/20101228204117/http://connect.microsoft.com/VisualStudio/feedback/details/98147/enum-getvalues) for now. – Sasha Apr 02 '17 at 01:04
-
`Max` is also Just-More-Clear, although this is interesting trivia to know :} – user2864740 Dec 26 '17 at 02:55
-
1Great, thanks! Just minor change, it needs to be *Cast
* instead of *Cast – Sam Nov 01 '18 at 07:27*. So it should be: `Enum.GetValues(typeof(Foo)).Cast ().Max();`
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();

- 2,179
- 19
- 16
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

- 101,809
- 122
- 424
- 632
-
See http://stackoverflow.com/questions/79126/create-generic-method-constraining-t-to-an-enum?rq=1 for this: if (!type.IsEnum) – Concrete Gannet Sep 10 '14 at 05:40
-
you can also add "struct" to your where as this will ensure it is a ValueType but not restrict it to Enum This is what I use: where T : struct, IComparable, IFormattable – jdawiz Aug 10 '17 at 17:06
-
2You could update your answer. In C# 7.3 you could actually do the extension method and also restrict to Enum type (instead of struct). – Nordes Jul 09 '18 at 05:14
-
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;
}
-
I've had cases where setting an Integer variable to a returned enum fails with type mismatch when a crazy value is supplied, so it's best to use a Long instead (if you're lazily not trapping the error properly!). – AjV Jsy Jul 31 '19 at 11:46
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());
}
}
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);
}
}
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.)

- 8,529
- 7
- 65
- 105
-
5Using GetUpperBound returns a count (4, not 40) for me: MyEnum {a = 0, b = 10, c = 20, d = 30, e = 40} – alirobe Mar 17 '10 at 05:11
-
Nice catch, I hadn't noticed that. OK, so this version is great for standard auto-enums, but not for enums with custom values. I guess the winner remains Mr Hamilton. :) – Engineer Mar 17 '10 at 23:10
-
GetUpperBound is good when your Enum has bitwise values. (ie - 1, 2, 4, 8, etc). For instance, if you were writing a unit test, you'd want to work through a loop w/ this many iterations: Math.Pow(2, Enum.GetValues(typeof(MyEnum)).GetUpperBound(0)) . – WEFX Aug 18 '14 at 15:41
-
What's wrong with Length (for the number of values in the enum)? Simpler is better. (Not that this answers the original question.) – Ian Goldby Sep 15 '16 at 11:03
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")
'''''''
-
Does not work when the array has gaps. It also works only by accident, because the element index happens to equal the value stored at that index. ```GetUpperBound()``` retrieves the highest possible **index** in the array returned by ```GetValues()```, not the highest value stored inside that array. – JensG Jun 01 '19 at 22:03
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!");
}

- 177
- 1
- 5
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.

- 955
- 1
- 12
- 13
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.

- 1,405
- 16
- 34