¿Cómo obtener el máximo valor de una enumeración?

  • Posibles duplicados de Encontrar el Valor más Alto en una Enumeración
  • Yo creo que el compilador podría manejar esto, en lugar de utilizar un Reflejo de la llamada. Una respuesta que se utiliza en tiempo de compilación método para obtener esta información podría recibir hasta mi voto.
InformationsquelleAutor jdelator | 2008-10-15

10 Comentarios

  1. 192

    Enum.GetValues() se parece a la devolución de los valores en orden, así que usted puede hacer algo como esto:

    //given this enum:
    public enum Foo
    {
        Fizz = 3, 
        Bar = 1,
        Bang = 2
    }
    
    //this gets Fizz
    var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Last();

    Editar

    Para aquellos que no estén dispuestos a leer a través de los comentarios: también se puede hacer de esta manera:

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

    … que va a trabajar cuando algunos de sus valores de enumeración son negativos.

    • Impresionante eso me gusta.
    • de niza. tomando ventaja de: «los elementos de La matriz son ordenados por los valores binarios de las constantes de enumeración.» de msdn.microsoft.com/en-us/library/system.enum.getvalues.aspx
    • Yo estaba golpeando mi cabeza, pensando que esta era realmente trivial, pero una solución elegante fue dado. También si usted desea obtener el valor de enumeración uso Convertir.ToInt32() después. Esto es para los resultados de google.
    • Si se ordenan por las representaciones binarias, ¿qué sucede con los valores enum que tienen un valor negativo? Los valores negativos en binario en realidad tienen el más alto orden de bits como un 1, ya que suelen ser representados usando 2 del complemento, que es la cantidad que al final de la matriz es -1.
    • Si vas a utilizar LINQ, ¿por qué no usar Max(), que es mucho más clara, y no depende de «parece»?
    • Max() sería demasiado trabajo. Dado que el enlace de arriba prueba mi hipótesis, aunque, yo diría que la Última() podría funcionar mejor ya no es necesario visitar cada elemento para ver cual es el máximo.
    • Funciona mejor, pero sólo si los valores de la enumeración no son negativos, lo que podría ser.
    • +1 solución Útil.
    • Yo voto por Max (), también. La Última() fallará si enum no son negativos, consulte aquí
    • No funcionará como se espera si enum tiene valores negativos.
    • href=»//web-beta.archive.org/web/20101228204117/http://connect.microsoft.com/VisualStudio/feedback/details/98147/enum-getvalues» >más correcto enlace por ahora.
    • Max también es Más Claro, aunque esto es muy interesante trivia a saber :}
    • Genial, gracias! Sólo un cambio menor, debe ser Cast<int> en lugar de Cast<Foo>. Por lo que debe ser: Enum.GetValues(typeof(Foo)).Cast<int>().Max();

  2. 35

    Estoy de acuerdo con Matt respuesta. Si usted sólo necesita min y max valores int, entonces usted puede hacerlo de la siguiente manera.

    Máximo:

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

    Mínimo:

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

    Según Matt Hamilton respuesta, pensé en crear un método de Extensión para él.

    Desde ValueType no es aceptado como un parámetro de tipo genérico restricción, no encontré una mejor manera de restringir T a Enum pero el siguiente.

    Cualquier idea será muy apreciada.

    PS. por favor, ignore mi VB implicitación, me encanta el uso de VB en este camino, que es la fuerza de VB y por eso me encanta VB.

    Howeva, aquí está:

    C#:

    static void Main(string[] args)
    {
        MyEnum x = GetMaxValue<MyEnum>();
    }
    
    public static TEnum GetMaxValue<TEnum>() 
        where TEnum : IComparable, IConvertible, IFormattable
        //In C#>=7.3 substitute with 'where TEnum : Enum', and remove the following check:
    {
        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
    • +1 Buen reutilizables solución.
    • Consulte stackoverflow.com/questions/79126/… para esto: if (!tipo.IsEnum)
    • usted puede también agregar «struct» a la que, como esto va a asegurar que es un tipo de valor, pero no se limitan a Enum Esto es lo que yo uso: donde T : struct, IComparable, IFormattable
    • Usted puede actualizar su respuesta. En C# 7.3 realmente podría hacer el método de extensión y también restringir a un tipo Enum (en lugar de la estructura).
  4. 13

    Esto es un poco nitpicky pero el verdadero valor máximo de cualquier enum es Int32.MaxValue (asumiendo que se trata de una enumeración derivados de int). Es perfectamente legal para poner en valor Int32 cualquier enum independientemente de si es o no efectivamente declarado un miembro con ese valor.

    Legal:

    enum SomeEnum
    {
        Fizz = 42
    }
    
    public static void SomeFunc()
    {
        SomeEnum e = (SomeEnum)5;
    }
    • De alguna manera yo realmente no creo que lo jdelator está buscando, pero +1 por divertido pedantism 🙂
    • a tu comentario para el uso de «pedantism»
    • @Cocowalla «pedante»
    • He tenido casos en donde la configuración de una variable de tipo Entero, a un ex enum falla con el tipo de desajuste cuando un loco valor es suministrado, así que es mejor utilizar un lugar (si estás perezosamente no captura el error correctamente!).
  5. 9

    Después intentó otra vez, llegué a este método de extensión:

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

    El uso de la Última función no se pudo obtener el valor máximo. El uso de la «max» función podría. Como:

     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);
            }
        }
  7. 4

    De acuerdo con Mateo J Sullivan, para C#:

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

    Realmente no estoy seguro de por qué alguien querría usar:

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

    …Como palabra-por-palabra, semánticamente hablando, no parece tener mucho sentido? (siempre es bueno tener diferentes formas, pero no veo la ventaja en el segundo.)

    • El uso de GetUpperBound devuelve un número (4, no 40) para mí: MyEnum {a = 0, b = 10, c = 20, d = 30, e = 40}
    • Buena captura, yo no había notado eso. OK, así que esta versión es ideal para el estándar de auto-enumeraciones, pero no para las enumeraciones con valores personalizados. Supongo que el ganador sigue siendo el Señor Hamilton. 🙂
    • GetUpperBound es buena, cuando su Enum tiene bit a bit valores. (ie – 1, 2, 4, 8, etc). Por ejemplo, si estuviera escribiendo una unidad de prueba, usted quiere trabajar a través de un bucle con este número de iteraciones: Matemáticas.Pow(2, Enum.GetValues(typeof(MyEnum)).GetUpperBound(0)) .
    • Lo que está mal con la Longitud (por el número de valores de la enumeración)? Sencillo es mejor. (No es que este responde a la pregunta original.)
    • Ya saben qué? Eso es exactamente lo que estaba buscando.
  8. 2

    Hay métodos para obtener información acerca de los tipos enumerados en el Sistema.Enum.

    Así, en un VB.Net proyecto en Visual Studio puedo «tipo de Sistema.Enum.» y el intellisense trae todo tipo de bondad.

    Un método en particular es el Sistema.Enum.GetValues(), que devuelve un array con los valores enumerados. Una vez que tenemos la matriz, usted debería ser capaz de hacer lo que sea apropiado para sus circunstancias particulares.

    En mi caso, mis valores enumerados comenzó en cero y se omite ningún número, por lo que para obtener el máximo valor para mi enum sólo necesito saber cómo muchos elementos en la matriz.

    VB.Net los fragmentos de código:

    '''''''
    
    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")
    
    '''''''
    • No funciona cuando la matriz tiene lagunas. También funciona sólo por accidente, debido a que el índice del elemento pasa a ser igual al valor almacenado en el índice. GetUpperBound() recupera la más alta posible de la índice en la matriz devuelta por GetValues(), no el más alto valor almacenado en el interior de la matriz.
  9. 2

    En F#, con una función de ayuda a convertir la enumeración de una secuencia:

    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   

    Corriendo…

    > tipo de Foo = | Fizz = 3 | Bang = 2 
    > val ToSeq : 'Un -> seq< B> cuando 'A : enum< B> 
    > val FooMax : Foo = Fizz 
    

    La when 'A : enum<'B> no es requerida por el compilador para la definición, pero es necesario para cualquier uso de ToSeq, incluso por una válida de tipo enum.

  10. 0

    No es utilizable en todas las circunstancias, pero a menudo me define el valor máximo de mí mismo:

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

    Por supuesto, esto no funciona cuando usted usar valores personalizados en una enumeración, pero a menudo puede ser una solución fácil.

Dejar respuesta

Please enter your comment!
Please enter your name here