Comment obtenir la valeur maximale d'une énumération?
Comment obtenir la valeur maximale d'une énumération?
Réponses:
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();
Éditer
Pour ceux qui ne veulent pas lire les commentaires: vous pouvez également le faire de cette façon:
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Max();
... qui fonctionnera lorsque certaines de vos valeurs d'énumération sont négatives.
Je suis d'accord avec la réponse de Matt. Si vous n'avez besoin que 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();
Selon la réponse de Matt Hamilton, j'ai pensé à créer une méthode d'extension pour cela.
Étant donné que ValueType
n'est pas acceptée comme une contrainte de paramètre de type générique, je ne l' ai pas trouvé une meilleure façon de limiter T
à , Enum
mais ce qui suit.
Toutes les idées seraient vraiment appréciées.
PS. s'il vous plaît ignorer 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:
static void Main(string[] args)
{
MyEnum x = GetMaxValue<MyEnum>(); //In newer versions of C# (7.3+)
MyEnum y = GetMaxValueOld<MyEnum>();
}
public static TEnum GetMaxValue<TEnum>()
where TEnum : Enum
{
return Enum.GetValues(typeof(TEnum)).Cast<TEnum>().Max();
}
//When C# version is smaller than 7.3, use this:
public static TEnum GetMaxValueOld<TEnum>()
where TEnum : IComparable, IConvertible, IFormattable
{
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
}
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
C'est légèrement pointilleux, mais la valeur maximale réelle de tout enum
est Int32.MaxValue
(en supposant que ce soit un enum
dérivé de int
). Il est parfaitement légal de jeter toute Int32
valeur à un tout , enum
peu importe si oui ou non elle a effectivement déclaré un membre à cette valeur.
Légal:
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 fonction Dernière 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);
}
}
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();
... Comme mot pour mot, sémantiquement parlant, cela ne semble pas avoir autant de sens? (toujours bon d'avoir des manières différentes, mais je ne vois pas l'avantage dans ce dernier.)
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 en mesure de faire ce qui convient à votre situation particulière.
Dans mon cas, mes valeurs énumérées ont commencé à zéro et n'ont ignoré aucun nombre, 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")
'''''''
GetUpperBound()
récupère l' index le plus élevé possible dans le tableau renvoyé par GetValues()
, et non la valeur la plus élevée stockée dans ce tableau.
En F #, avec une fonction d'assistance pour convertir l'énumération en 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
L'exécution ...
> tapez 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 est requis pour toute utilisation de ToSeq, même par un type enum valide.
Il n'est pas utilisable en toutes 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 lorsque vous utilisez des valeurs personnalisées dans une énumération, mais cela peut souvent être une solution simple.
J'ai utilisé ce qui suit lorsque j'avais besoin des valeurs min et max de mon enum. Je viens de définir un min égal à la valeur la plus basse de l'énumération et un max égal à la valeur la plus élevée de l'énumération en tant que valeurs d'énumération elles-mêmes.
public enum ChannelMessageTypes : byte
{
Min = 0x80, // Or could be: Min = NoteOff
NoteOff = 0x80,
NoteOn = 0x90,
PolyKeyPressure = 0xA0,
ControlChange = 0xB0,
ProgramChange = 0xC0,
ChannelAfterTouch = 0xD0,
PitchBend = 0xE0,
Max = 0xE0 // Or could be: Max = PitchBend
}
// I use it like this to check if a ... is a channel message.
if(... >= ChannelMessageTypes.Min || ... <= ChannelMessages.Max)
{
Console.WriteLine("Channel message received!");
}