Uzyskaj wartość int z enum w C #

1821

Mam klasę o nazwie Questions(liczba mnoga). W tej klasie jest wyliczenie zwane Question(liczba pojedyncza), które wygląda tak.

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

W Questionsklasie mam get(int foo)funkcję, która zwraca do tego Questionsobiekt foo. Czy istnieje prosty sposób na usunięcie wartości całkowitej z wyliczenia, aby móc zrobić coś takiego Questions.Get(Question.Role)?

Jim
źródło
31
Na odwrót: cast-int-to-enum-in-c-sharp .
nawfal
11
Wiem, że spóźniłem się na imprezę, ale zamiast zdefiniować metodę, get(int foo)którą można zdefiniować, a get(Question foo)następnie wykonać rzutowanie wewnątrz metody, można wywołać metodę jakoQuestions.Get(Question.Role)
Joe

Odpowiedzi:

2350

Wystarczy rzucić wyliczenie, np

int something = (int) Question.Role;

Powyższe będzie działać dla ogromnej większości wyliczeń, które widzisz na wolności, ponieważ domyślnym rodzajem wyliczenia jest int.

Jednak, jak wskazuje Cecilphillip , wyliczenia mogą mieć różne podstawowe typy. Jeśli enum jest zadeklarowana jako uint, longlub ulong, powinno być oddane do typu wyliczenia; np. dla

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

powinieneś użyć

long something = (long)StarsInMilkyWay.Wolf424B;
Tetraneutron
źródło
23
@Harry, to nie prawda. Możesz utworzyć Wyliczenie bez rzutowania, nie jest to wymagane. i przypisuję numer tylko w szczególnych przypadkach, przez większość czasu pozostawiam go jako wartość domyślną. ale możesz to zrobić enum Test { Item = 1 }i zobaczyć, że 1 == (int)Test.Itemto jest równe.
Jaider
33
@Jaider (int)Test.ItemThat is cast! () jest jawnym operatorem rzutowania.
Sinthia V
48
@Sinthia V powiedział, że możesz go stworzyć bez rzucania, co jest poprawne
Paul Ridgway
7
Jeśli typem źródłowym enum Questionnie było, intale longta obsada obetnie Rolecałkowitą wartość!
quaylar
1
Kiedy akceptujesz Enumparametr, wiesz, że możesz uzyskać tylko stałą liczbę możliwych wartości całkowitych. Z drugiej strony, jeśli weźmiesz po prostu an int, musisz sprawdzić, czy intmieści się w akceptowanych wartościach, co komplikuje kod. Zawsze możesz przesłonić swoje podpisy, takie jak: `` public void MyMethod (int x) {// zrób coś z x} public void MyMethod (Enum x) {this.MyMethod ((int) x); } ``
postrzegane
307

Ponieważ wyliczenia może być dowolny integralną typu ( byte, int, short, itd.), Bardziej wydajny sposób, aby uzyskać wartości bazowej całka wyliczenia byłoby skorzystać z GetTypeCodemetody w połączeniu z Convertklasą:

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

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

Powinno to działać niezależnie od podstawowego typu całki.

Cecilphillip
źródło
32
Ta technika udowodniła mi swoją wartość, gdy mamy do czynienia z typem ogólnym, w którym T: enum (właściwie T: struct, IConvertible, ale to inna historia).
aboy021
1
Jak zmodyfikowałbyś to, aby wydrukować wartość szesnastkową strony? Ten przykład pokazuje wartość dziesiętną. Problem w tym, że varjest to typ object, więc musisz go rozpakować, a robi się bałagan, niż bym chciał.
Mark Lakata,
2
Myślę, że powinieneś zmienić przykład object val = Convert...etcna varw swoim przykładzie zawsze będzie object.
Mesh
2
@TimAbell Wszystko, co mogę naprawdę powiedzieć, to to, że odkryliśmy, że dynamicznie kompilowane strony aspx (gdzie trzeba wdrożyć pliki .cs na serwerze na żywo) przypisują liczby całkowite różnie do każdej wartości. Oznaczało to, że zserializowane obiekty jedna maszyna, deserializowały się z różnymi wartościami na innej maszynie i skutecznie ulegały uszkodzeniu (powodując godziny zamieszania). Podnieśliśmy to w MS i wydaje mi się, że pamiętam, że powiedzieli, że nie można zagwarantować, że automatyczne generowane liczby całkowite będą takie same, gdy zostaną zbudowane w różnych wersjach ram.
NickG
4
@TimAbell Przy oddzielnej okazji programista usunął przestarzałą / nieużywaną wartość Enum, powodując, że wszystkie inne wartości w sekwencji są wyłączone o jeden. W związku z tym nasze standardy kodowania wymagają teraz, aby identyfikatory były zawsze podawane jawnie, w przeciwnym razie dodanie / usunięcie lub nawet automatyczne formatowanie kodu (np. Sortowanie alfabetyczne) zmieni wszystkie wartości powodujące uszkodzenie danych. Radziłbym każdemu, aby wyraźnie określił wszystkie liczby całkowite Enum. Jest to niezwykle ważne, jeśli koreluje z wartościami przechowywanymi zewnętrznie (w bazie danych).
NickG
199

Zadeklaruj jako klasę statyczną o stałych publicznych:

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;
}

A potem możesz odwołać się do niego jako Question.Rolei zawsze będzie to ewaluacja do intczegoś, co zdefiniujesz jako.

PablosBicicleta
źródło
31
Użyłbym, static readonly intponieważ stałe są kompilowane do ich twardych wartości. Zobacz stackoverflow.com/a/755693/492
Blok CAD
96
To rozwiązanie w rzeczywistości nie zapewnia rzeczywistej korzyści z silnie typowanych wyliczeń. Gdybym chciał przekazać na przykład parametr GameState-enum do określonej metody, kompilator nie powinien pozwalać mi na przekazywanie żadnej zmiennej wewnętrznej jako parametru.
thgc
12
@CADBloke, dlatego właśnie tego używałbyś, consta nie static readonlydlatego, że za każdym razem, gdy porównujesz static readonly, wywołujesz metodę, aby uzyskać wartość zmiennej, podczas gdy z constporównujesz bezpośrednio dwa typy wartości.
Blockloop
3
@ brettof86 Tak, const byłby szybszy, jeśli ograniczenie kompilacji nigdy nie będzie problemem, to wszystko będzie dobrze.
CAD bloke
2
@Zack Nie wyjaśniłem tego zbyt dobrze, compilation limitationmam na myśli to, że wartość jest zakodowana na stałe podczas kompilacji, więc każda zmiana tej wartości wymagałaby ponownej kompilacji wszystkich używających ją zestawów. Jestem skłonny zgodzić się z tobą na temat użytkowania, ponieważ zmiana wartości miałaby daleko idące konsekwencje.
CAD CAD
87
Question question = Question.Role;
int value = (int) question;

Spowoduje w value == 2.

jerryjvl
źródło
34
Pytanie zmiennej tymczasowej jest niepotrzebne.
Gishu,
1
Więc coś takiego: pytania. Pobierz (Convert.ToInt16 (Question.Applications))
Jim
6
Możesz po prostu rzucić w dowolnym kierunku; jedyną rzeczą do obejrzenia jest to, że wyliczenia niczego nie egzekwują (wartość wyliczenia może wynosić 288, mimo że nie ma pytania o tym numerze)
Marc Gravell
@jim: Nie, po prostu wpisz wartość: Questions.Get ((int) Question.Applications);
Guffa
1
@Gishu Można powiedzieć, że to ... wątpliwe. ;)
Felix D.
79

W powiązanej notatce, jeśli chcesz uzyskać intwartość System.Enum, podaj etutaj:

Enum e = Question.Role;

Możesz użyć:

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);

Dwa ostatnie są po prostu brzydkie. Wolę pierwszy.

nawfal
źródło
1
Drugi jest jednak najszybszy.
Johan B
1
Jako ktoś, kto jest przyzwyczajony do używania Mixins w modowaniu Minecraft, drugi wydaje się oczywistym zwycięzcą.
Sollace
40

To łatwiejsze niż myślisz - wyliczenie to już int. Trzeba tylko przypomnieć:

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2
Michael Petrotta
źródło
15
Nitpick: ten enum jest już int. Inne wyliczenia mogą być różnych typów - spróbuj „enum SmallEnum: bajt {A, B, C}”
mqp
9
Absolutnie prawdziwe. Odwołanie do C #: „Każdy typ wyliczenia ma typ bazowy, którym może być dowolny typ całkowy oprócz char.”
Michael Petrotta
33

Przykład:

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

A w kodzie z tyłu, aby uzyskać wartość wyliczenia:

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

lub

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

Wyliczenia będą zwiększane o 1 i możesz ustawić wartość początkową. Jeśli nie ustawisz wartości początkowej, początkowo zostanie przypisana jako 0.

Peter Mortensen
źródło
6
Czy to się faktycznie kompiluje?
Peter Mortensen
Czy coś, co jest Rajem, może być również Rahulem lub Priyanką? Twoje wartości są sprzeczne i powinny podwoić się, aby być unikalne, np. 0, 1, 2, 4, 8 itd. To jest mój główny problem z wyliczeniami.
Timothy Gonzalez
@TimothyGonzalez faktycznie wylicza po prostu policz 1, jeśli nie podasz wyraźnie ich wartości;)
derHugo 10.10
@derHugo, które zależy, jeśli przyjmujesz, że wartości liczbowe to podstawa 10 lub podstawa 2.
Timothy Gonzalez,
@TimothyGonzalez dobrze nie ma wiele do przyjęcia ... po prostu zwrócić uwagę, że domyślnie oni tylko liczyć się 1z intwyjątkiem jawnie zdefiniować inaczej
derHugo
28

Niedawno zrezygnowałem z używania wyliczeń w moim kodzie na rzecz zamiast używania klas z chronionymi konstruktorami i predefiniowanymi instancjami statycznymi (dzięki Roelof - C # Upewnij się, że Valum Enum Values ​​- Futureproof Method ).

W związku z tym poniżej przedstawiam teraz ten problem (w tym niejawną konwersję do / z 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)
}

Zaletą tego podejścia jest to, że otrzymujesz wszystko, co miałbyś z wyliczenia, ale twój kod jest teraz znacznie bardziej elastyczny, więc jeśli musisz wykonywać różne działania w oparciu o wartość Question, możesz umieścić logikę w Questionsobie (tj. W preferowanym OO moda), w przeciwieństwie do umieszczania wielu instrukcji w całym kodzie w celu rozwiązania każdego scenariusza.


NB: Odpowiedź zaktualizowana 27.04.2018, aby skorzystać z funkcji C # 6; tzn. wyrażenia deklaracyjne i definicje treści wyrażeń lambda. Zobacz historię zmian dla oryginalnego kodu. Ma to tę zaletę, że definicja jest nieco mniej szczegółowa; która była jedną z głównych skarg na podejście tej odpowiedzi.

JohnLBevan
źródło
2
Sądzę, że jest to kompromis między jawną obsadą a kodem, który musisz napisać, aby go obejść. Nadal uwielbiam implementację, tylko szkoda, że ​​nie była tak długa. +1
Lankymart
3
Użyłem kilku różnych typów klas o podobnej strukturze. Uważam, że działają cuda, próbując zastosować metodologię „nie pozwól mi być idiotą później”.
James Haug,
20

Jeśli chcesz uzyskać liczbę całkowitą dla wartości wyliczonej, która jest przechowywana w zmiennej, dla której typ byłby Question, na przykład w metodzie, możesz po prostu zrobić to, co napisałem w tym przykładzie:

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();
}

Spowoduje to zmianę tytułu okna na 4, ponieważ zmienną Geselecteerdjest Talen.Nederlands. Jeśli zmienię to na Talen.Portugeesi wywołam ponownie metodę, tekst zmieni się na 3.

Mathijs Van Der Slagt
źródło
3
kodowanie w języku holenderskim. o jej.
WiseStrawberry
Niestety, takie podejście daje słabą wydajność, im częściej go używasz. Wypróbowałem to w moim kodzie i wraz z upływem czasu moja aplikacja działała coraz wolniej, z coraz mniejszym zużyciem procesora. Sugerowało to, że wątki na coś czekały - zakładam jakiś sposób wyrzucania elementów bezużytecznych, prawdopodobnie z powodu boksowania parametru wyliczania do ToInt32 (). Przełączając się na prostą metodę int.Parse (), byłem w stanie całkowicie wyeliminować tę słabą wydajność, a wydajność pozostała taka sama bez względu na czas działania kodu.
Greg
16

Aby upewnić się, że istnieje wartość wyliczenia, a następnie ją przeanalizować, możesz również wykonać następujące czynności.

// 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
źródło
14

Może mi tego brakowało, ale czy ktoś próbował prostej ogólnej metody rozszerzenia?

To działa świetnie dla mnie. W ten sposób można uniknąć rzutowania typu w interfejsie API, ale ostatecznie powoduje to operację zmiany typu. Jest to dobry przypadek do zaprogramowania Roslyn, aby kompilator stworzył dla ciebie metodę GetValue <T>.

    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
źródło
Być może dlatego, że wykonywanie (int) customFlag jest mniej typowe do pisania i czy mniej więcej to samo?
Tim Keating,
Re „Może mi tego brakowało, ale czy ktoś próbował prostej ogólnej metody rozszerzenia ?” : SixOThree powiedział Zamiast tego użyj metody rozszerzenia ”, a Bronek powiedział „Możesz to zrobić, implementując metodę rozszerzenia do zdefiniowanego typu wyliczenia” .
Peter Mortensen,
13

Jeszcze jeden sposób, aby to zrobić:

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

Spowoduje to:

Name: Role, Value: 2
plavozont
źródło
12
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

... to dobra deklaracja.

Musisz rzucić wynik na int tak:

int Question = (int)QuestionType.Role

W przeciwnym razie typ jest nadal QuestionType .

Ten poziom ścisłości jest sposobem C #.

Jedną z możliwości jest użycie deklaracji klasy zamiast:

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
}

Deklarowanie jest mniej eleganckie, ale nie trzeba go umieszczać w kodzie:

int Question = QuestionType.Role

Alternatywnie możesz czuć się bardziej komfortowo z Visual Basic, który zaspokaja tego rodzaju oczekiwania w wielu obszarach.

WonderWorker
źródło
11
int number = Question.Role.GetHashCode();

numberpowinien mieć wartość 2.

JaimeArmenta
źródło
GetHashCode to jeden ze sposobów na uzyskanie wartości z wspólnej maski Enum
ThanhLD
Należy pamiętać, że jest to tylko "legit" o bool*, byte, ushort, int, i uint**. GetHashCode dla innych typów modyfikuje wartość, np. Robi niektóre przesunięcia bitów i xory. (* 1/0, ** casted do int oczywiście). Ale w sumie nie rób tego, chyba że jest to twój prywatny kod.
AnorZaken
10

Możesz to zrobić, implementując metodę rozszerzenia do zdefiniowanego typu wyliczenia:

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

Upraszcza to uzyskanie wartości int bieżącej wartości wyliczenia:

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

lub

int value = Question.Role.getNumberValue();
Bronek
źródło
5
Bronek, stworzyłeś nieinformacyjną składnię za pomocą (nietypowej metody rozszerzenia btw), której napisanie zajmuje więcej czasu. Nie widzę, jak to jest lepsze niż oryginalne rozwiązanie Tetraneutron. Nie zamieniajmy tego w czat, pomoc jest zawsze mile widziana w stosie i wszyscy są tutaj, aby pomóc. Proszę przyjąć mój komentarz za konstruktywną krytykę.
Benjamin Gruenbaum,
2
Benjamin, po pierwsze, dlaczego usunąłeś mój komentarz? Nie rozumiem twoich decyzji - może ktoś inny przez społeczność zgodziłby się z moim komentarzem. Po drugie, moje rozwiązanie obejmuje jeden Tetraneutron i dokładnie jest łatwiejsze i mniej pisanie, ponieważ metoda rozszerzenia jest sugerowana przez IntelliSense. Więc myślę, że twoja decyzja nie jest bezstronna i reprezentatywna. Widzę wiele podobnych odpowiedzi na Stack i jest OK. W każdym razie używam mojego rozwiązania i być może niektórzy ludzie wybiorą moje rozwiązanie w przyszłości, ale te ujemne punkty utrudniają znalezienie. przede wszystkim jest poprawne, a nie kopiowane.
Bronek,
3
@Bronek Jeśli mnie nie pingujesz, nie otrzymuję żadnej odpowiedzi, że odpowiedziałeś. I nie nie usunąć swój komentarz Nie mam zdolności lub chcesz zrobić. Najprawdopodobniej przyszedł i usunął mod - możesz go oflagować, aby zwrócić uwagę moderatora i zapytać, dlaczego lub jeszcze lepiej - zapytaj na Meta Stack Overflow . Mam opinię na temat twojego rozwiązania z punktu widzenia programowania, co jest całkowicie słuszne - od tego są na początek komentarze, nie trzeba brać tego do siebie.
Benjamin Gruenbaum,
8

Zamiast tego użyj metody rozszerzenia:

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

A użycie jest nieco ładniejsze:

var intValue = Question.Role.IntValue();
SixOThree
źródło
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
źródło
suit - „10. (gry karciane) Każdy z zestawów kart kart wyróżniających się kolorem i / lub specyficznymi emblematami, takimi jak pik, kier, karo lub trefl tradycyjnych kart do gry w Anglo, Hiszpanie i Francji.”
Peter Mortensen,
Wyjaśnienie przykładowego kodu byłoby w porządku ( edytując odpowiedź , a nie tutaj w komentarzach).
Peter Mortensen,
zero jest generalnie zarezerwowane dla stanu nieustawionego / nieznanego w wyliczeniach, co jest niezwykłe, aby tak to zdefiniować
Chad Grant
6

Posługiwać się:

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

Spowoduje to value == 2.

Jest to prawdą tylko wtedy, gdy wyliczenie mieści się w int.

GinCanhViet
źródło
1
Jest to prawdą tylko wtedy, gdy wyliczenie mieści się intoczywiście w środku , ponieważ GetHashCodezwraca liczbę całkowitą.
RB.
5

Ponieważ wyliczenia można zadeklarować za pomocą wielu typów pierwotnych, użyteczna może być ogólna metoda rozszerzenia do rzutowania dowolnego typu wyliczenia.

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
źródło
4

Poniżej przedstawiono metodę rozszerzenia

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
źródło
4

Mój ulubiony hack z int lub mniejszymi wyliczeniami:

GetHashCode();

Dla wyliczenia

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

To,

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

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

wyjścia

one
1
1
max
2147483647
2147483647
min
-2147483648
-2147483648

Zrzeczenie się:

Nie działa na wyliczenia oparte na długim.

Erik Karlsson
źródło
3

Najłatwiejszym rozwiązaniem jest przeciążenie Get(int)metody w ten sposób:

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

gdzie [modifiers]ogólnie może być taki sam jak dla Get(int)metody. Jeśli nie możesz edytować Questionsklasy lub z jakiegoś powodu nie chcesz, możesz przeładować metodę, pisząc rozszerzenie:

public static class Extensions
{
    public static Questions Get(this Questions qs, Question q)
    {
        return qs.Get((int)q);
    }
}
Grx70
źródło
3

Przykład, który chciałbym zasugerować „aby uzyskać wartość„ int ”z wyliczenia”, to

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

int answer = (int)Sample.Book;

Teraz odpowiedź będzie wynosić 1.

Vivek
źródło
3

Posługiwać się:

Question question = Question.Role;
int value = Convert.ToInt32(question);
Peter Mortensen
źródło
2

Wypróbuj ten zamiast konwersji enum na 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
źródło
2

W języku Visual Basic powinno to być:

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

Private value As Integer = CInt(Question.Role)
VPP
źródło
3
Pytanie dotyczy C #.
Ctrl S,
2
Tytuł mówi „Uzyskaj wartość int z enum w C #” .
Peter Mortensen,
0

Wymyśliłem tę metodę rozszerzenia, która obejmuje bieżące funkcje językowe. Korzystając z dynamiki, nie muszę robić z tego ogólnej metody i określać typ, który sprawia, że ​​wywołanie jest prostsze i spójne:

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
źródło
proszę nie, możesz to wszystko zrobić w jednym wierszu Convert.Changetype (e, e.GetTypeCode ()) i odzyskać obiekt, bez potrzeby dynamiki ani metody rozszerzenia
Chad Grant
Nie będę się zgadzać z używaniem Konwertuj. Po prostu użycie obsady byłoby łatwiejsze. Moim zamiarem było przekonwertowanie dowolnego wyliczenia na jego wartość bez użycia obsady. Pozwala to na zmianę typu enum bez konieczności zmiany wszystkich powiązanych rzutów - ale kiedy to się dzieje ?. Metoda rozszerzenia działa poprawnie. Mam jednak z tym problem, ponieważ ponieważ jest on dynamiczny, kompilator nie może sprawdzać typu (najwyraźniej dla całej instrukcji), co oznacza, że ​​sprawdzanie typu następuje po uruchomieniu - nie jest to dobre rozwiązanie. Myślę, że wrócę do obsad.
Jeff
1
Nie powiedziałem, że używaj go zamiast obsady, tylko że ten kod jest nonsensowny i niczego nie osiąga, w rzeczywistości problem się pogarsza. Polecam usunięcie tego rozwiązania
Chad Grant