Question

Comment obtenir la valeur maximale d'une énumération ?

Était-ce utile?

La solution

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 également procéder de cette façon :

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

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

Autres conseils

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

Minimum:

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

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

Etant donné que ValueType n'est pas accepté comme contrainte de paramètre de type générique, je n'ai pas trouvé de meilleur moyen de restreindre T à Enum mais le suivant.

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

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

Howeva, la 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

Ceci est un peu tatillon, mais la valeur maximale réelle de toute énumération est Int32.MaxValue (en supposant que cela soit une énumération dérivée de int). Il est parfaitement légal de convertir toute valeur Int32 en une énumération, qu'elle ait ou non déclaré un membre avec cette valeur.

Juridique:

enum SomeEnum
{
    Fizz = 42
}

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

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

L'utilisation de la dernière fonction n'a pas pu obtenir la valeur maximale. Utilisez le & Quot; max & Quot; fonction pourrait. J'aime:

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

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

... Du point de vue sémantique, mot à mot, 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 ces dernières.)

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 soulève 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 en mesure 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 sauté aucun chiffre, donc pour obtenir la valeur maximale de mon énumération, j'ai juste besoin de savoir combien d'éléments se trouvaient 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")

'''''''

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> when '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 d'énum valide.

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

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.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top