Timothy Shields
Timothy Shields

Reputation: 79521

Min and Max operations on enum values

Using C#, how can I take the min or max of two enum values?

For example, if I have

enum Permissions
{
    None,
    Read,
    Write,
    Full
}

is there a method that lets me do Helper.Max(Permissions.Read, Permissions.Full) and get Permissions.Full, for example?

Upvotes: 12

Views: 10612

Answers (7)

Felix Price
Felix Price

Reputation: 11

While this question is quite old, it shows up at the top for some searches I did, so here we go, with a little more detail than the existing answer:

Permissions p1 = Permissions.Read;
Permissions p2 = Permissions.Write;

var pMax = (Permissions)Math.Max( (int)p1, (int)p2 );

Alternatively in case the enum is long based:

var pMax = (Permissions)Math.Max( (long)p1, (long)p2 );

Why does this work?

  • enum values can be cast to int (or 'long'), which represents their position
  • An int can be cast back to an enum
  • Math.Max() apparently works on int

Sidenotes:

  • Appearently this also works for the mininum with Math.Min()
  • IEnumerable.Max() and IEnumerable.Min() can be used if you need the maximum or minimum of more than two enum values (if you don't mind System.Linq).

Upvotes: 0

Tevya
Tevya

Reputation: 864

There is a one-stop means for getting the min and max for any enumeration. All it assumes is that the representation type is an int.

    public Tuple<int,int> GetMinMaxOfEnumeration<T>()
    {
        if (!typeof (T).IsEnum)
        {
            throw new ArgumentException("Type must be an enumeration");
        }
        var valuesAsInt = Enum.GetValues(typeof (T)).Cast<int>().OrderBy(n => n).ToArray();
        return new Tuple<int, int>(valuesAsInt.First(), valuesAsInt.Last());
    }

Upvotes: -1

TruthOf42
TruthOf42

Reputation: 2107

can be called with 2 or more parameters

    public static T GetMaxEnum<T>(params T[] enums) where T : struct, IConvertible
    {
        if (enums.Length < 2)
        {
            throw new InvalidEnumArgumentException();
        }
        return enums.Max();
    }

Upvotes: 3

Valmir Cinquini
Valmir Cinquini

Reputation: 381

I think you want something like this:

public enum Enum1
{
    A_VALUE,
    B_VALUE,
    C_VALUE
}

public enum Enum2
{
    VALUE_1,
    VALUE_2,
    VALUE_3
}

class Program
{
    static void Main(string[] args)
    {
        Program p = new Program();

        Console.WriteLine(p.EnumMin<Enum1>());
        Console.WriteLine(p.EnumMax<Enum2>());

    }


    T EnumMin<T>()
    {
        T ret; ;
        Array x = Enum.GetValues(typeof(T));
        ret  = (T) x.GetValue(0);
        return ret;
    }

    T EnumMax<T>()
    {
        T ret; ;
        Array x = Enum.GetValues(typeof(T));
        ret = (T)x.GetValue(x.Length-1);
        return ret;
    }

}

Upvotes: -1

Lee
Lee

Reputation: 144166

Enums implement IComparable so you can use:

public static T Min<T>(T a, T b) where T : IComparable
{
    return a.CompareTo(b) <= 0 ? a : b;
}

Upvotes: 19

user22467
user22467

Reputation:

Since enums are convertible to integer types, you can just do:

   var permissions1 = Permissions.None;
   var permissions2 = Permissions.Full;
   var maxPermission = (Permissions) Math.Max((int) permissions1, (int) permissions2);

Note that this could cause issues if your enum is based on an unsigned type, or a type longer than 32 bits (i.e., long or ulong), but in that case you can just change the type you are casting the enums as to match the type declared in your enum.

I.e., for an enum declared as:

enum Permissions : ulong
{
    None,
    Read,
    Write,
    Full
}

You would use:

   var permissions1 = Permissions.None;
   var permissions2 = Permissions.Full;
   var maxPermission = (Permissions) Math.Max((ulong) permissions1, (ulong) permissions2);

Upvotes: 4

Timothy Shields
Timothy Shields

Reputation: 79521

This is what I came up with because I couldn't find anything in .NET that did this.

public static class EnumHelper
{
    public static T Min<T>(T a, T b)
    {
        return (dynamic)a < (dynamic)b ? a : b;
    }

    public static T Max<T>(T a, T b)
    {
        return (dynamic)a > (dynamic)b ? a : b;
    }
}

Upvotes: 0

Related Questions