tags:

views:

3290

answers:

7

How do you get the max value of an enum?

+21  A: 

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();
Matt Hamilton
Awesome I like that one.
cfeduke
nice. 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
I 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
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
If you're going to use LINQ, why not use Max(), which is much clearer, and doesn't rely on "seems to"?
Marc Gravell
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
It performs better, but only if the values of the enum aren't negative, which they could be.
ICR
+6  A: 

This is slighly 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;
        }
JaredPar
Somehow I don't really think that's what jdelator is looking for, but +1 for amusing pedantism :)
Cocowalla
@Cocowalla +1 to your comment for using "pedantism"
Nick
+2  A: 

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

Since ValueType is not accepted as a generic type delimiter, I didn't find a better way to restrict T to Enum. Any ideas would be really appreciated.

PS. please ignore my VB implicitness, I love using VB in this way.

Howeva, here it is:

C#:

static void Main(string[] args)
{
    MyEnum x = GetMaxValue<MyEnum>();
}

public static TEnum GetMaxValue<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
Shimmy
+1  A: 

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

'''''''
A: 

Use the Last function could not get the max value. Use the "max" fuction 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);
        }
    }
Eric Feng
A: 

After tried another time, I got thsi 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());        
        }
}
Eric Feng
+1  A: 

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

Nick Wiggill
Using GetUpperBound returns a count (4, not 40) for me: MyEnum {a = 0, b = 10, c = 20, d = 30, e = 40}
dingle_thunk
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. :)
Nick Wiggill