Wie erhält man den Maximalwert einer Aufzählung?
Wie erhält man den Maximalwert einer Aufzählung?
Antworten:
Enum.GetValues () scheint die Werte in der angegebenen Reihenfolge zurückzugeben, sodass Sie Folgendes tun können:
// given this enum:
public enum Foo
{
Fizz = 3,
Bar = 1,
Bang = 2
}
// this gets Fizz
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Last();
Bearbeiten
Für diejenigen, die nicht bereit sind, die Kommentare durchzulesen: Sie können dies auch folgendermaßen tun:
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Max();
... was funktioniert, wenn einige Ihrer Aufzählungswerte negativ sind.
Ich stimme Matts Antwort zu. Wenn Sie nur minimale und maximale int-Werte benötigen, können Sie dies wie folgt tun.
Maximal:
Enum.GetValues(typeof(Foo)).Cast<int>().Max();
Minimum:
Enum.GetValues(typeof(Foo)).Cast<int>().Min();
Nach der Antwort von Matt Hamilton habe ich darüber nachgedacht, eine Erweiterungsmethode dafür zu erstellen.
Da dies ValueType
nicht als generische Einschränkung für Typparameter akzeptiert wird, habe ich keinen besseren Weg gefunden, mich T
auf Enum
Folgendes zu beschränken .
Irgendwelche Ideen wären sehr dankbar.
PS. Bitte ignorieren Sie meine VB-Implizität. Ich liebe es, VB auf diese Weise zu verwenden. Das ist die Stärke von VB und deshalb liebe ich VB.
Howeva, hier ist es:
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
Dies ist etwas pingelig, aber der tatsächliche Maximalwert von jedem enum
ist Int32.MaxValue
(vorausgesetzt, es ist ein enum
abgeleiteter von int
). Es ist völlig legal, einen Int32
Wert in einen beliebigen Wert umzuwandeln, enum
unabhängig davon, ob tatsächlich ein Mitglied mit diesem Wert deklariert wurde oder nicht.
Legal:
enum SomeEnum
{
Fizz = 42
}
public static void SomeFunc()
{
SomeEnum e = (SomeEnum)5;
}
Nachdem ich es ein anderes Mal versucht hatte, bekam ich diese Erweiterungsmethode:
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());
}
}
Verwenden Sie die Funktion Letzte konnte den Maximalwert nicht erhalten. Verwenden Sie die Funktion "max". Mögen:
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);
}
}
In Übereinstimmung mit Matthew J Sullivan für C #:
Enum.GetValues(typeof(MyEnum)).GetUpperBound(0);
Ich bin mir wirklich nicht sicher, warum jemand Folgendes verwenden möchte:
Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Last();
... Semantisch gesehen scheint es Wort für Wort nicht so sinnvoll zu sein? (Es ist immer gut, verschiedene Wege zu haben, aber ich sehe den Nutzen in letzterem nicht.)
Unter System.Enum gibt es Methoden zum Abrufen von Informationen zu Aufzählungstypen.
In einem VB.Net-Projekt in Visual Studio kann ich also "System.Enum" eingeben. und der Intellisense bringt alle Arten von Güte hervor.
Eine Methode ist insbesondere System.Enum.GetValues (), die ein Array der aufgezählten Werte zurückgibt. Sobald Sie das Array haben, sollten Sie in der Lage sein, alles zu tun, was für Ihre besonderen Umstände angemessen ist.
In meinem Fall begannen meine Aufzählungswerte bei Null und übersprangen keine Zahlen. Um den Maximalwert für meine Aufzählung zu erhalten, muss ich nur wissen, wie viele Elemente sich im Array befanden.
VB.Net-Code-Schnipsel:
'''''''
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()
Ruft den höchstmöglichen Index in dem von zurückgegebenen Array ab GetValues()
, nicht den höchsten in diesem Array gespeicherten Wert.
In F # mit einer Hilfsfunktion zum Konvertieren der Aufzählung in eine Sequenz:
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
Laufen es ...
> Geben Sie Foo = | ein Fizz = 3 | Bang = 2 > val ToSeq: 'A -> seq <' B> wenn 'A: enum <' B> > val FooMax: Foo = Fizz
Das when 'A : enum<'B>
wird vom Compiler für die Definition nicht benötigt, ist jedoch für jede Verwendung von ToSeq erforderlich, selbst für einen gültigen Aufzählungstyp.
Es ist nicht unter allen Umständen verwendbar, aber ich definiere den Maximalwert oft selbst:
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));
Dies funktioniert natürlich nicht, wenn Sie benutzerdefinierte Werte in einer Aufzählung verwenden, aber häufig kann dies eine einfache Lösung sein.
Ich habe Folgendes verwendet, als ich die Min- und Max-Werte meiner Aufzählung benötigte. Ich habe gerade ein min gleich dem niedrigsten Wert der Aufzählung und ein max gleich dem höchsten Wert in der Aufzählung als Aufzählungswerte selbst gesetzt.
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!");
}