web-dev-qa-db-fra.com

Obtenir la valeur maximale d'une énumération

Comment obtenez-vous la valeur maximale d'un enum?

124
jdelator

Enum.GetValues ​​() semble renvoyer les valeurs dans l'ordre, vous pouvez donc faire quelque chose comme ceci:

// given this enum:
public enum Foo
{
    Fizz = 3, 
    Bar = 1,
    Bang = 2
}

// this gets Fizz
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Last();

Modifier

Pour ceux qui ne veulent pas lire les commentaires: Vous pouvez aussi le faire de la manière suivante:

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

... ce qui fonctionnera lorsque certaines de vos valeurs enum sont négatives.

179
Matt Hamilton

Je suis d'accord avec la réponse de Matt. Si vous avez juste besoin de valeurs min et max int, vous pouvez le faire comme suit.

Maximum:

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

Le minimum:

Enum.GetValues(typeof(Foo)).Cast<int>().Min();
33
Karanvir Kang

Selon la réponse de Matt Hamilton, je pensais créer une méthode d'extension.

Puisque ValueType n'est pas accepté en tant que contrainte de paramètre de type générique, je n'ai pas trouvé de meilleur moyen de restreindre T à Enum, mais comme suit.

Toutes les idées seraient vraiment appréciées.

PS. veuillez ignorer mon implicite VB, j'adore utiliser VB de cette façon, c'est la force de VB et c'est pourquoi j'aime VB.

Howeva, le voici:

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
20
Shimmy

C'est un peu difficile, mais la valeur maximale réelle de n'importe quelle énumération est Int32.MaxValue (en supposant que c'est une énumération dérivée de int). Il est parfaitement légal de convertir une valeur Int32 en une énumération, qu'elle ait ou non déclaré un membre avec cette valeur. 

Légal:

enum SomeEnum
{
    Fizz = 42
}

public static void SomeFunc()
{
    SomeEnum e = (SomeEnum)5;
}
13
JaredPar

Après avoir essayé une autre fois, j'ai eu cette méthode d'extension:

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

Utilisez la dernière fonction n'a pas pu obtenir la valeur maximale. Utilisez la fonction "max" pourrait. Comme:

 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);
        }
    }
5
Eric Feng

En accord avec Matthew J Sullivan, pour C #:

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

Je ne sais vraiment pas pourquoi quelqu'un voudrait utiliser:

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

... En tant que mot, sémantiquement parlant, cela ne semble pas avoir beaucoup de sens? (C'est toujours bien d'avoir différentes manières, mais je ne vois pas l'avantage dans la dernière.)

4
Engineer

Il existe des méthodes pour obtenir des informations sur les types énumérés sous System.Enum.

Ainsi, dans un projet VB.Net dans Visual Studio, je peux taper "System.Enum". et l'intellisense évoque toutes sortes de bontés.

Une méthode en particulier est System.Enum.GetValues ​​(), qui renvoie un tableau des valeurs énumérées. Une fois que vous avez le tableau, vous devriez être capable de faire tout ce qui est approprié à votre situation particulière.

Dans mon cas, mes valeurs énumérées ont commencé à zéro et n’ont pas omis de chiffres. Par conséquent, pour obtenir la valeur maximale de mon enum, il me suffit de savoir combien d’éléments figurent dans le tableau.

Extraits de code VB.Net:

'''''''

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

'''''''
3
Matthew J Sullivan

En F #, avec une fonction d'assistance pour convertir l'énumération en une séquence:

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   

Le lancer ...

> type Foo = | Fizz = 3 | Bang = 2 
> Val ToSeq: 'A -> seq <' B> quand 'A: enum <' B> 
>. Val FooMax: Foo = Fizz 

Le when 'A : enum<'B> n'est pas requis par le compilateur pour la définition, mais pour toute utilisation de ToSeq, même par un type enum valide.

2
Stephen Hosking

Ce n'est pas utilisable dans toutes les circonstances, mais je définis souvent moi-même la valeur max:

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

Bien sûr, cela ne fonctionnera pas si vous utilisez des valeurs personnalisées dans une énumération, mais cela peut souvent être une solution facile.

0
yvan vander sanden