Pergunta

Como você obter o valor máximo de um enum?

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top