Pergunta
Como você obter o valor máximo de um enum?
Solução
Enum.GetValues ??() parece retornar os valores em ordem, de modo que você pode fazer algo como isto:
// given this enum:
public enum Foo
{
Fizz = 3,
Bar = 1,
Bang = 2
}
// this gets Fizz
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Last();
Editar
Para aqueles que não querem ler os comentários: Você pode também fazê-lo desta maneira:
var lastFoo = Enum.GetValues(typeof(Foo)).Cast<Foo>().Max();
... que irá funcionar quando alguns dos seus valores enum são negativos.
Outras dicas
Eu concordo com a resposta de Matt. Se você precisa apenas de valores mínimo e máximo int, então você pode fazê-lo da seguinte forma.
máxima:
Enum.GetValues(typeof(Foo)).Cast<int>().Max();
mínima:
Enum.GetValues(typeof(Foo)).Cast<int>().Min();
De acordo com a resposta de Matt Hamilton, pensei em criar um método de extensão para ele.
Desde ValueType
não é aceite como um genérico restrição tipo de parâmetro, eu não encontrar uma maneira melhor para restringir T
para Enum
mas a seguir.
Todas as ideias seria muito apreciada.
PS. ignore o meu VB implicitness, eu amo usar VB, desta forma, que é a força do VB e é por isso que eu amo VB.
Howeva, aqui está:
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
Este é um pouco detalhista, mas o valor máximo real de qualquer enum é Int32.MaxValue (assumindo que é um enum derivada de int). É perfeitamente legal para lançar qualquer valor Int32 a um qualquer enum independentemente de se é ou não realmente declarou um membro com esse valor.
Legal:
enum SomeEnum
{
Fizz = 42
}
public static void SomeFunc()
{
SomeEnum e = (SomeEnum)5;
}
Depois tentou outra vez, eu tenho esse método de extensão:
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());
}
}
Use a última função não poderia obter o valor máximo. Use a função de "max" podia. Como:
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);
}
}
De acordo com Matthew J Sullivan, para C #:
Enum.GetValues(typeof(MyEnum)).GetUpperBound(0);
Eu estou realmente não tenho certeza por que alguém iria querer usar:
Enum.GetValues(typeof(MyEnum)).Cast<MyEnum>().Last();
... Como a palavra por palavra, semanticamente falando, não parece fazer tanto sentido? (Sempre bom ter formas diferentes, mas eu não ver o benefício no último.)
Existem métodos para obter informações sobre os tipos enumerados sob System.Enum.
Assim, em um projeto VB.Net no Visual Studio eu posso digitar "System.Enum." ea intellisense traz todos os tipos de bondade.
Um método, em particular, é System.Enum.GetValues ??(), que retorna uma matriz dos valores enumerados. Uma vez que você tem a matriz, você deve ser capaz de fazer o que é apropriado para suas circunstâncias particulares.
No meu caso, meus valores enumerados começou em zero e pulado nenhum número, de modo a obter o valor máximo para o meu enum Eu só preciso saber quantos elementos estavam na matriz.
VB.Net trechos de código:
'''''''
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")
'''''''
Em F #, com uma função auxiliar para converter o enum a uma sequência:
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
Executá-lo ...
> type Foo = | Fizz = 3 | Bang = 2 > val ToSeq : 'A -> seq<'B> when 'A : enum<'B> > val FooMax : Foo = Fizz
O when 'A : enum<'B>
não é exigido pelo compilador para a definição, mas é necessária para qualquer uso de ToSeq, mesmo por um tipo enum válido.
Não é utilizável em todas as circunstâncias, mas muitas vezes eu definir o valor máximo mim mesmo:
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));
É claro que isso não vai funcionar quando você usar valores personalizados em um enum, mas muitas vezes pode ser uma solução fácil.