Bir numaralamanın maksimum değerini nasıl elde edersiniz?
Bir numaralamanın maksimum değerini nasıl elde edersiniz?
Yanıtlar:
Enum.GetValues () değerleri sırayla döndürüyor gibi görünüyor, bu nedenle şöyle bir şey yapabilirsiniz:
// given this enum:
public enum Foo
{
Fizz = 3,
Bar = 1,
Bang = 2
}
// this gets Fizz
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Last();
Düzenle
Yorumları okumak istemeyenler için: Bunu şu şekilde de yapabilirsiniz:
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Max();
... bu, enum değerlerinden bazıları negatif olduğunda işe yarar.
Matt'in cevabına katılıyorum. Yalnızca minimum ve maksimum int değerlerine ihtiyacınız varsa, bunu aşağıdaki gibi yapabilirsiniz.
Maksimum:
Enum.GetValues(typeof(Foo)).Cast<int>().Max();
Minimum:
Enum.GetValues(typeof(Foo)).Cast<int>().Min();
Matt Hamilton'ın cevabına göre, bunun için bir Uzatma yöntemi oluşturmayı düşündüm.
Yana ValueType
bir genel tür parametre kısıtlaması olarak kabul edilmez, ben kısıtlamak için daha iyi bir yol bulamadık T
için Enum
Aşağdakiler.
Herhangi bir fikir gerçekten takdir edilecektir.
PS. lütfen benim VB örtüklüğümü görmezden gelin, VB'yi bu şekilde kullanmayı seviyorum, bu VB'nin gücü ve bu yüzden VB'yi seviyorum.
Howeva, işte burada:
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
Bu biraz titizdir, ancak herhangi enum
birinin gerçek maksimum değeri Int32.MaxValue
(bunun enum
türetildiği varsayılarak int
). Bu Int32
değere enum
sahip bir üye ilan edip etmediğine bakılmaksızın herhangi bir değeri herhangi bir değere dönüştürmek tamamen yasaldır .
Yasal:
enum SomeEnum
{
Fizz = 42
}
public static void SomeFunc()
{
SomeEnum e = (SomeEnum)5;
}
Başka bir zaman denedikten sonra, bu uzatma yöntemini aldım:
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());
}
}
Son işlevi kullanın, maksimum değeri alamadı. "Max" işlevini kullanabilir. Sevmek:
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);
}
}
Matthew J Sullivan ile uyumlu olarak, C # için:
Enum.GetValues(typeof(MyEnum)).GetUpperBound(0);
Gerçekten neden birinin kullanmak isteyeceğinden emin değilim:
Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Last();
... Kelime kelime, anlamsal olarak konuşulduğunda, o kadar mantıklı görünmüyor mu? (farklı yollara sahip olmak her zaman iyidir, ancak ikincisinde faydasını görmüyorum.)
System.Enum altında numaralandırılmış türler hakkında bilgi almak için yöntemler vardır.
Yani, Visual Studio'daki bir VB.Net projesinde "System.Enum" yazabilirim. ve zeka her türden iyiliği ortaya çıkarır.
Özellikle bir yöntem, numaralandırılmış değerlerin bir dizisini döndüren System.Enum.GetValues () yöntemidir. Diziyi aldıktan sonra, özel koşullarınıza uygun olanı yapabilmelisiniz.
Benim durumumda, numaralandırılmış değerlerim sıfırdan başladı ve hiç sayı atlamadı, bu nedenle numaramın maksimum değerini elde etmek için dizide kaç öğenin olduğunu bilmem gerekiyor.
VB.Net kod parçacıkları:
'''''''
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()
olası en yüksek dizini alır GetValues()
.
F # 'da, numaralandırmayı bir diziye dönüştürmek için bir yardımcı işlevle:
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
Çalıştırmak ...
> Foo yazın = | Fizz = 3 | Patlama = 2 > val ToSeq: 'A -> seq <' B>, 'A: enum <' B> olduğunda > val FooMax: Foo = Fizz
when 'A : enum<'B>
Tanımı için derleyici tarafından gerekli değildir, ancak bu bile geçerli bir enum türüne göre, ToSeq her türlü kullanımından gereklidir.
Numaramın minimum ve maksimum değerlerine ihtiyacım olduğunda aşağıdakileri kullandım. Sadece numaralandırmanın en düşük değerine eşit bir min ve numaralandırmadaki enum değer olarak en yüksek değere eşit bir maks belirledim.
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!");
}
Her koşulda kullanılamaz, ancak genellikle maksimum değeri kendim tanımlarım:
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));
Elbette bu, bir numaralandırmada özel değerler kullandığınızda işe yaramaz, ancak çoğu zaman kolay bir çözüm olabilir.