简体   繁体   中英

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?

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;
}

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 (ie, 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.

Ie, 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);

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();
    }

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;
    }
}

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;
    }

}

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());
    }

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM