Obter valor int de enum em C #

1825

Eu tenho uma classe chamada Questions(plural). Nesta classe, há um enum chamado Question(singular) que se parece com isso.

public enum Question
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

Na Questionsclasse, tenho uma get(int foo)função que retorna um Questionsobjeto para isso foo. Existe uma maneira fácil de obter o valor inteiro da enumeração para que eu possa fazer algo assim Questions.Get(Question.Role)?

jim
fonte
31
Por outro lado: elenco-int-enum-em-c-sharp .
Nawfal
11
Eu sei que estou atrasado para a festa, mas, em vez de definir seu método, como get(int foo)você pode defini-lo, get(Question foo)assim como fazer sua fundição dentro do método, você pode chamá-lo comoQuestions.Get(Question.Role)
Joe

Respostas:

2354

Basta lançar o enum, por exemplo

int something = (int) Question.Role;

O exemplo acima funcionará para a grande maioria de enumerações que você vê na natureza, como o tipo subjacente padrão de uma enumeração int.

No entanto, como cecilphillip aponta, as enumerações podem ter diferentes tipos subjacentes. Se um ENUM é declarado como um uint, longou ulong, deve ser convertido para o tipo de enumeração; por exemplo, para

enum StarsInMilkyWay:long {Sun = 1, V645Centauri = 2 .. Wolf424B = 2147483649};

você deveria usar

long something = (long)StarsInMilkyWay.Wolf424B;
Tetraneutron
fonte
23
@ Harry não é verdade. Você pode criar enumeração sem conversão, não é necessário. e só atribuo número em casos especiais, na maioria das vezes, deixo como valor padrão. mas você pode fazer enum Test { Item = 1 }e ver que 1 == (int)Test.Itemé igual.
28512 Jaider
33
@ Jaider (int)Test.ItemIsso é um elenco! () é o operador de conversão explícita.
Sinthia V 26/07/12
48
@Sinthia V ele disse que você pode criar -lo sem a carcaça, o que é correto
Paul Ridgway
7
Se o tipo subjacente de enum Questionnão foi, intmas longessa conversão truncará Roleo valor integral de s!
quaylar
1
Quando você aceita um Enumcomo parâmetro, sabe que é apenas um número fixo de possíveis valores integrais que você pode obter. Por outro lado, se você escolher simplesmente um int, precisará validar se isso intestá dentro dos valores aceitos., Complicando o código. Você sempre pode substituir suas assinaturas como `` public void MyMethod (int x) {// faça algo com x} public void MyMethod (Enum x) {this.MyMethod ((int) x); } `` ``
percebus
307

Desde Enums pode ser qualquer tipo integral ( byte, int, short, etc.), uma forma mais robusta para obter o valor integral subjacente da enumeração seria fazer uso do GetTypeCodemétodo em conjunto com a Convertclasse:

enum Sides {
    Left, Right, Top, Bottom
}
Sides side = Sides.Bottom;

object val = Convert.ChangeType(side, side.GetTypeCode());
Console.WriteLine(val);

Isso deve funcionar independentemente do tipo integral subjacente.

cecilphillip
fonte
32
Essa técnica provou meu valor ao lidar com um tipo genérico em que T: enum (na verdade T: struct, IConvertible, mas essa é uma história diferente).
aboy021
1
Como você modificaria isso para imprimir o valor hexadecimal de side? Este exemplo mostra o valor decimal. O problema é que varé do tipo object, então você precisa retirá-lo da caixa e ele fica mais confuso do que eu gostaria.
precisa saber é o seguinte
2
Eu acho que você deve mudar o exemplo para object val = Convert...etco varno seu exemplo sempre será object.
Malha
2
@ TimAbell Tudo o que posso dizer é que descobrimos que páginas aspx compiladas dinamicamente (nas quais é necessário implantar os arquivos .cs no servidor ativo) estavam atribuindo os números inteiros de maneira diferente para cada valor. Isso significava que os objetos serializados de uma máquina estavam desserializando com valores diferentes em uma máquina diferente e se corrompendo efetivamente (causando horas de confusão). Criamos isso com o MS e lembro-me de que eles disseram que os números inteiros gerados automaticamente não eram iguais quando construídos em diferentes versões de estrutura.
NickG
4
@TimAbell Em uma ocasião separada, um desenvolvedor excluiu um valor Enum obsoleto / não utilizado, fazendo com que todos os outros valores na sequência fiquem fora de um. Dessa forma, nossos padrões de codificação agora exigem que os IDs sejam sempre especificados explicitamente; caso contrário, adicionar / excluir ou até formatar automaticamente o código (por exemplo, ordenar alfabeticamente) alterará todos os valores que causam corrupção de dados. Eu recomendo fortemente que alguém especifique todos os números inteiros de Enum explicitamente. Isso é extremamente importante se eles se correlacionarem com valores armazenados externamente (banco de dados).
NickG
199

Declare-o como uma classe estática com constantes públicas:

public static class Question
{
    public const int Role = 2;
    public const int ProjectFunding = 3;
    public const int TotalEmployee = 4;
    public const int NumberOfServers = 5;
    public const int TopBusinessConcern = 6;
}

E então você pode fazer referência a ele como Question.Role, e ele sempre é avaliado como um intou o que você definir como.

Pablosétrica
fonte
31
Eu usaria static readonly intporque constantes são compiladas em seus valores concretos. Veja stackoverflow.com/a/755693/492
CAD bloke
96
Essa solução, na verdade, não fornece o benefício real de enumerações fortemente tipadas. Se eu apenas quisesse passar um parâmetro GameState-enum para um método específico, por exemplo, o compilador não deveria me permitir passar nenhuma variável int como parâmetro.
Thgc
12
@CADBloke, que é precisamente o motivo pelo qual você usaria, conste não static readonlyporque toda vez que você compara static readonlyvocê está fazendo uma chamada de método para obter o valor da variável, enquanto constvocê está comparando dois tipos de valor diretamente.
blockloop
3
@ brettof86 Sim, uma const seria mais rápida, se a limitação da compilação nunca for um problema, está tudo bem.
Bloke CAD
2
@ Zack Eu não expliquei isso muito bem, compilation limitationquero dizer que o valor é codificado quando você o compila, para que qualquer alteração nesse valor exija que todos os assemblies que o usem precisem ser recompilados. Estou inclinado a concordar com você sobre o uso, pois alterar os valores teria implicações de longo alcance.
CAD bloke
87
Question question = Question.Role;
int value = (int) question;

Irá resultar em value == 2.

jerryjvl
fonte
34
A questão variável temporária é desnecessária.
Gishu 03/06/2009
1
Portanto, algo como este Questions.Get (Convert.ToInt16 (Question.Applications))
jim
6
Você pode simplesmente transmitir em qualquer direção; a única coisa a observar é que as enumerações não impõem nada (o valor da enumeração pode ser 288, mesmo que não exista uma pergunta com esse número)
Marc Gravell
@ Jim: Não, basta lançar o valor: Questions.Get ((int) Question.Applications);
Guffa
1
@ Gishu Você poderia dizer que é ... questionável. ;)
Felix D.
79

Em uma nota relacionada, se você deseja obter o intvalor System.Enum, especifique eaqui:

Enum e = Question.Role;

Você pode usar:

int i = Convert.ToInt32(e);
int i = (int)(object)e;
int i = (int)Enum.Parse(e.GetType(), e.ToString());
int i = (int)Enum.ToObject(e.GetType(), e);

Os dois últimos são feios. Eu prefiro o primeiro.

nawfal
fonte
1
O segundo é o mais rápido.
Johan B
1
Como alguém que está acostumado a usar Mixins no Minecraft modding, o segundo parece ser o vencedor óbvio.
Sollace 14/10/19
40

É mais fácil do que você pensa - um enum já é um int. Só precisa ser lembrado:

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2
Michael Petrotta
fonte
15
Nitpick: esse enum já é um int. Outros enums pode haver diferentes tipos - tentar "enum SmallEnum: byte {A, B, C}"
MQP
9
Absolutamente verdadeiro. Referência de C #: "Todo tipo de enumeração tem um tipo subjacente, que pode ser qualquer tipo integral, exceto char."
Michael Petrotta
33

Exemplo:

public Enum EmpNo
{
    Raj = 1,
    Rahul,
    Priyanka
}

E no código por trás para obter o valor enum:

int setempNo = (int)EmpNo.Raj; // This will give setempNo = 1

ou

int setempNo = (int)EmpNo.Rahul; // This will give setempNo = 2

As enums serão incrementadas em 1 e você poderá definir o valor inicial. Se você não definir o valor inicial, ele será atribuído como 0 inicialmente.

Peter Mortensen
fonte
6
Isso realmente compila?
31516 Peter Mortensen
Pode algo que é um Raj ser também um Rahul ou um Priyanka? Seus valores entram em conflito e devem dobrar para serem únicos, por exemplo, 0, 1, 2, 4, 8, etc. Essa é minha principal preocupação com enumerações.
Timothy Gonzalez
@TimothyGonzalez realmente ENUMS simplesmente contar 1 acima se você não especificar explicitamente seu valor;)
derHugo
@derHugo que depende se você assumir os valores numéricos para ser base 10 ou base 2.
Timothy Gonzalez
@TimothyGonzalez bem não há muito para assumir ... Eu só apontou que, por padrão eles apenas contar-se 1em intnão ser que você definir explicitamente o contrário
derHugo
28

Recentemente, converti o uso de enumerações no meu código em vez de usar classes com construtores protegidos e instâncias estáticas predefinidas (graças ao Roelof - C # Garantir valores válidos de enumeração - método à prova de futuro ).

À luz disso, veja abaixo como eu abordaria esse problema agora (incluindo a conversão implícita de / para int).

public class Question
{
    // Attributes
    protected int index;
    protected string name;
    // Go with a dictionary to enforce unique index
    //protected static readonly ICollection<Question> values = new Collection<Question>();
    protected static readonly IDictionary<int,Question> values = new Dictionary<int,Question>();

    // Define the "enum" values
    public static readonly Question Role = new Question(2,"Role");
    public static readonly Question ProjectFunding = new Question(3, "Project Funding");
    public static readonly Question TotalEmployee = new Question(4, "Total Employee");
    public static readonly Question NumberOfServers = new Question(5, "Number of Servers");
    public static readonly Question TopBusinessConcern = new Question(6, "Top Business Concern");

    // Constructors
    protected Question(int index, string name)
    {
        this.index = index;
        this.name = name;
        values.Add(index, this);
    }

    // Easy int conversion
    public static implicit operator int(Question question) =>
        question.index; //nb: if question is null this will return a null pointer exception

    public static implicit operator Question(int index) =>        
        values.TryGetValue(index, out var question) ? question : null;

    // Easy string conversion (also update ToString for the same effect)
    public override string ToString() =>
        this.name;

    public static implicit operator string(Question question) =>
        question?.ToString();

    public static implicit operator Question(string name) =>
        name == null ? null : values.Values.FirstOrDefault(item => name.Equals(item.name, StringComparison.CurrentCultureIgnoreCase));


    // If you specifically want a Get(int x) function (though not required given the implicit converstion)
    public Question Get(int foo) =>
        foo; //(implicit conversion will take care of the conversion for you)
}

A vantagem dessa abordagem é que você obtém tudo o que teria da enumeração, mas seu código agora é muito mais flexível; portanto, se você precisar executar ações diferentes com base no valor de Question, poderá colocar a lógica em Questionsi (por exemplo, no OO preferido moda), em vez de colocar muitas instruções de caso em todo o código para lidar com cada cenário.


NB: Resposta atualizada em 2018-04-27 para fazer uso dos recursos do C # 6; ou seja, expressões de declaração e definições de corpo de expressão lambda. Veja o histórico de revisões para obter o código original. Isso tem o benefício de tornar a definição um pouco menos detalhada; que havia sido uma das principais reclamações sobre a abordagem dessa resposta.

JohnLBevan
fonte
2
Eu acho que é a troca entre elenco explícito e o código que você precisa escrever para contorná-lo. Ainda amo a implementação apenas gostaria que não fosse tão demorado. +1
Lankymart
3
Eu usei vários tipos diferentes de classes estruturadas de maneira semelhante a isso. Acho que eles fazem maravilhas ao tentar seguir a metodologia "não me deixe ser um idiota mais tarde".
James Haug
20

Se você deseja obter um número inteiro para o valor de enum que é armazenado em uma variável, para o qual o tipo seria Question, para usar, por exemplo, em um método, basta fazer isso que escrevi neste exemplo:

enum Talen
{
    Engels = 1, Italiaans = 2, Portugees = 3, Nederlands = 4, Duits = 5, Dens = 6
}

Talen Geselecteerd;    

public void Form1()
{
    InitializeComponent()
    Geselecteerd = Talen.Nederlands;
}

// You can use the Enum type as a parameter, so any enumeration from any enumerator can be used as parameter
void VeranderenTitel(Enum e)
{
    this.Text = Convert.ToInt32(e).ToString();
}

Isso mudará o título da janela para 4, porque a variável Geselecteerdé Talen.Nederlands. Se eu mudar para Talen.Portugeese chamar o método novamente, o texto será alterado para 3.

Mathijs Van Der Slagt
fonte
3
codificação em holandês. Oh céus.
WiseStrawberry
Infelizmente, essa abordagem oferece desempenho ruim quanto mais você a usa. Eu tentei em algum código meu e, com o passar do tempo, meu aplicativo ficou cada vez mais lento, com menos e menos uso da CPU. Isso implicava que os threads estavam aguardando algo - estou assumindo algum tipo de coleta de lixo, possivelmente devido ao encaixe do parâmetro enum em ToInt32 (). Ao mudar para um simples int.Parse (), consegui eliminar completamente esse desempenho ruim, e o desempenho permaneceu o mesmo, independentemente do tempo de execução do código.
Greg
16

Para garantir que exista um valor de enumeração e depois analisá-lo, você também pode fazer o seguinte.

// Fake Day of Week
string strDOWFake = "SuperDay";

// Real Day of Week
string strDOWReal = "Friday";

// Will hold which ever is the real DOW.
DayOfWeek enmDOW;

// See if fake DOW is defined in the DayOfWeek enumeration.
if (Enum.IsDefined(typeof(DayOfWeek), strDOWFake))
{
    // This will never be reached since "SuperDay"
    // doesn't exist in the DayOfWeek enumeration.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWFake);
}
// See if real DOW is defined in the DayOfWeek enumeration.
else if (Enum.IsDefined(typeof(DayOfWeek), strDOWReal))
{
    // This will parse the string into it's corresponding DOW enum object.
    enmDOW = (DayOfWeek)Enum.Parse(typeof(DayOfWeek), strDOWReal);
}

// Can now use the DOW enum object.
Console.Write("Today is " + enmDOW.ToString() + ".");
Nathon
fonte
14

Talvez eu tenha perdido, mas alguém já tentou um método simples de extensão genérica?

Isso funciona muito bem para mim. Você pode evitar o tipo de conversão na sua API dessa maneira, mas, em última análise, resulta em uma operação de tipo de alteração. Este é um bom caso para programar o Roslyn para que o compilador crie um método GetValue <T> para você.

    public static void Main()
    {
        int test = MyCSharpWrapperMethod(TestEnum.Test1);

        Debug.Assert(test == 1);
    }

    public static int MyCSharpWrapperMethod(TestEnum customFlag)
    {
        return MyCPlusPlusMethod(customFlag.GetValue<int>());
    }

    public static int MyCPlusPlusMethod(int customFlag)
    {
        // Pretend you made a PInvoke or COM+ call to C++ method that require an integer
        return customFlag;
    }

    public enum TestEnum
    {
        Test1 = 1,
        Test2 = 2,
        Test3 = 3
    }
}

public static class EnumExtensions
{
    public static T GetValue<T>(this Enum enumeration)
    {
        T result = default(T);

        try
        {
            result = (T)Convert.ChangeType(enumeration, typeof(T));
        }
        catch (Exception ex)
        {
            Debug.Assert(false);
            Debug.WriteLine(ex);
        }

        return result;
    }
}
Doug
fonte
Possivelmente porque fazer (int) customFlag é menos digitado e faz mais ou menos a mesma coisa?
Tim Keating
Re "Talvez eu tenha perdido, mas alguém já tentou um método simples de extensão genérica ?" : SixOThree disse "Em vez disso, use um método de extensão " e Bronek disse "Você pode fazer isso implementando um método de extensão para o seu tipo de enum definido" .
Peter Mortensen
13

Mais uma maneira de fazer isso:

Console.WriteLine("Name: {0}, Value: {0:D}", Question.Role);

Isso resultará em:

Name: Role, Value: 2
plavozont
fonte
12
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

... é uma boa declaração.

Você precisa converter o resultado para int da seguinte maneira:

int Question = (int)QuestionType.Role

Caso contrário, o tipo é imóvel QuestionType.

Esse nível de rigor é o modo C #.

Uma alternativa é usar uma declaração de classe:

public class QuestionType
{
    public static int Role = 2,
    public static int ProjectFunding = 3,
    public static int TotalEmployee = 4,
    public static int NumberOfServers = 5,
    public static int TopBusinessConcern = 6
}

É menos elegante declarar, mas você não precisa convertê-lo no código:

int Question = QuestionType.Role

Como alternativa, você pode se sentir mais confortável com o Visual Basic, que atende a esse tipo de expectativa em muitas áreas.

WonderWorker
fonte
11
int number = Question.Role.GetHashCode();

numberdeve ter o valor 2.

JaimeArmenta
fonte
GetHashCode é uma maneira de obter o valor de Enum máscara comum
ThanhLD
Note-se que este é apenas "legítimo" para bool*, byte, ushort, int, e uint**. O GetHashCode para outros tipos modifica o valor, por exemplo, alguns turnos de bits e xors. (* 1/0, ** convertido para int, é claro). Mas, no geral, não faça isso, a menos que seja seu próprio código privado.
AnorZaken 18/02
10

Você pode fazer isso implementando um método de extensão para o seu tipo de enum definido:

public static class MyExtensions
{
    public static int getNumberValue(this Question questionThis)
    {
        return (int)questionThis;
    }
}

Isso simplifica a obtenção do valor int do valor atual da enumeração:

Question question = Question.Role;
int value = question.getNumberValue();

ou

int value = Question.Role.getNumberValue();
Bronek
fonte
5
Bronek, o que você fez foi criar uma sintaxe não informativa por meio de um método de extensão (não genérico) que realmente leva mais tempo para ser escrito. Não vejo como é melhor que a solução original da Tetraneutron. Não vamos transformar isso em um bate-papo, a ajuda é sempre bem-vinda no stackoverflow e todos aqui estão aqui para ajudar. Por favor, tome meu comentário como crítica construtiva.
Benjamin Gruenbaum
2
Benjamin, antes de tudo, por que você excluiu meu comentário? Eu não entendo suas decisões - talvez alguém da comunidade concorde com o meu comentário. O método de extensão é sugerido pelo IntelliSense. esses pontos negativos dificultam a localização. Acima de tudo, está correto e não é copiado.
BrOdk
3
@Bronek Se você não me enviar um ping, não recebo nenhuma indicação de que você respondeu. Eu fiz não excluir seu comentário que não têm a capacidade ou quer fazê-lo. Provavelmente um mod apareceu e o excluiu - você pode sinalizá-lo para atenção do moderador e perguntar por que ou melhor ainda - pergunte no Meta Stack Overflow . Eu tenho uma opinião sobre a sua solução do ponto de vista da programação que está perfeitamente à minha direita - é para isso que os comentários servem, para começar, sem necessidade de considerá-la pessoal.
Benjamin Gruenbaum 7/08
8

Use um método de extensão:

public static class ExtensionMethods
{
    public static int IntValue(this Enum argEnum)
    {
        return Convert.ToInt32(argEnum);
    }
}

E o uso é um pouco mais bonito:

var intValue = Question.Role.IntValue();
SixOThree
fonte
7
public enum Suit : int
{
    Spades = 0,
    Hearts = 1,
    Clubs = 2,
    Diamonds = 3
}

Console.WriteLine((int)(Suit)Enum.Parse(typeof(Suit), "Clubs"));

// From int
Console.WriteLine((Suit)1);

// From a number you can also
Console.WriteLine((Suit)Enum.ToObject(typeof(Suit), 1));

if (typeof(Suit).IsEnumDefined("Spades"))
{
    var res = (int)(Suit)Enum.Parse(typeof(Suit), "Spades");
    Console.Out.WriteLine("{0}", res);
}
Gauravsa
fonte
naipe - "10. (jogos de cartas) Cada um dos conjuntos de um baralho distinguido por cor e / ou emblemas específicos, como espadas, copas, diamantes ou clubes das tradicionais cartas de jogar anglo-hispânicas e francesas."
Peter Mortensen
Uma explicação do código de exemplo estaria em ordem ( editando sua resposta , não aqui nos comentários).
Peter Mortensen
zero é geralmente reservada para o estado unset / unkown em enums, incomum para defini-lo assim
Chad Grant
6

Usar:

Question question = Question.Role;
int value = question.GetHashCode();

Isso resultará em value == 2.

Isso só é verdade se o enum se encaixar dentro de um int.

GinCanhViet
fonte
1
Isso só é verdade se o enum se encaixar dentro de um intcurso, pois GetHashCoderetorna um número inteiro.
RB.
5

Como as enumerações podem ser declaradas com vários tipos primitivos, um método de extensão genérico para converter qualquer tipo de enumeração pode ser útil.

enum Box
{
    HEIGHT,
    WIDTH,
    DEPTH
}

public static void UseEnum()
{
    int height = Box.HEIGHT.GetEnumValue<int>();
    int width = Box.WIDTH.GetEnumValue<int>();
    int depth = Box.DEPTH.GetEnumValue<int>();
}

public static T GetEnumValue<T>(this object e) => (T)e;
Jeffrey Ferreiras
fonte
4

A seguir está o método de extensão

public static string ToEnumString<TEnum>(this int enumValue)
{
    var enumString = enumValue.ToString();
    if (Enum.IsDefined(typeof(TEnum), enumValue))
    {
        enumString = ((TEnum) Enum.ToObject(typeof (TEnum), enumValue)).ToString();
    }
    return enumString;
}
Kamran Shahid
fonte
4

Meu hack favorito com enums int ou menores:

GetHashCode();

Para um enum

public enum Test
{
    Min = Int32.MinValue,
    One = 1,
    Max = Int32.MaxValue,
}

Este,

var values = Enum.GetValues(typeof(Test));

foreach (var val in values)
{
    Console.WriteLine(val.GetHashCode());
    Console.WriteLine(((int)val));
    Console.WriteLine(val);
}

saídas

one
1
1
max
2147483647
2147483647
min
-2147483648
-2147483648

Aviso Legal:

Não funciona para enumerações baseadas em muito tempo.

Erik Karlsson
fonte
3

A solução mais fácil que consigo pensar é sobrecarregar o Get(int)método desta maneira:

[modifiers] Questions Get(Question q)
{
    return Get((int)q);
}

onde [modifiers]geralmente pode ser o mesmo que para o Get(int)método Se você não pode editar a Questionsclasse ou, por algum motivo, não quiser, pode sobrecarregar o método escrevendo uma extensão:

public static class Extensions
{
    public static Questions Get(this Questions qs, Question q)
    {
        return qs.Get((int)q);
    }
}
Grx70
fonte
3

O exemplo que eu gostaria de sugerir "para obter um valor 'int' de uma enumeração" é

public enum Sample
{
    Book = 1, 
    Pen = 2, 
    Pencil = 3
}

int answer = (int)Sample.Book;

Agora a resposta será 1.

Vivek
fonte
3

Usar:

Question question = Question.Role;
int value = Convert.ToInt32(question);
Peter Mortensen
fonte
2

Tente este em vez de converter enum para int:

public static class ReturnType
{
    public static readonly int Success = 1;
    public static readonly int Duplicate = 2;
    public static readonly int Error = -1;        
}
Nalan Madheswaran
fonte
2

No Visual Basic, deve ser:

Public Enum Question
    Role = 2
    ProjectFunding = 3
    TotalEmployee = 4
    NumberOfServers = 5
    TopBusinessConcern = 6
End Enum

Private value As Integer = CInt(Question.Role)
VPP
fonte
3
A questão é para c #.
Ctrl S
2
O título diz "Obter valor int de enum em C #" .
Peter Mortensen
0

Eu vim com esse método de extensão que inclui recursos de idioma atuais. Ao usar dinâmico, não preciso fazer disso um método genérico e especificar o tipo que mantém a chamada mais simples e consistente:

public static class EnumEx
{
    public static dynamic Value(this Enum e)
    {
        switch (e.GetTypeCode())
        {
            case TypeCode.Byte:
            {
                return (byte) (IConvertible) e;
            }

            case TypeCode.Int16:
            {
                return (short) (IConvertible) e;
            }

            case TypeCode.Int32:
            {
                return (int) (IConvertible) e;
            }

            case TypeCode.Int64:
            {
                return (long) (IConvertible) e;
            }

            case TypeCode.UInt16:
            {
                return (ushort) (IConvertible) e;
            }

            case TypeCode.UInt32:
            {
                return (uint) (IConvertible) e;
            }

            case TypeCode.UInt64:
            {
                return (ulong) (IConvertible) e;
            }

            case TypeCode.SByte:
            {
                return (sbyte) (IConvertible) e;
            }
        }

        return 0;
    }
Jeff
fonte
por favor, não, você pode fazer tudo isso em uma linha Convert.ChangeType (e, e.GetTypeCode ()) e obter um objeto de volta, sem necessidade de dinâmica ou um método de extensão
Chad Grant
Discordo do uso do Convert. Apenas usar um elenco seria mais fácil. Minha intenção era ser capaz de converter qualquer enumeração em seu valor sem usar uma conversão. Isso permite a alteração do tipo de enum sem precisar alterar todos os lançamentos associados - mas quando isso acontece? O método de extensão funciona corretamente. No entanto, estou tendo um problema com isso, pois, como é dinâmico, o complier não pode digitar check (para toda a instrução aparentemente), o que significa que a verificação de tipo ocorre quando executada - não é uma boa solução. Acho que voltarei aos elencos.
Jeff
1
Eu não disse que usá-lo em excesso, apenas que esse código não faz sentido e não realiza nada, na verdade piora o problema. Eu recomendaria remover esta solução
Chad Grant