Holen Sie sich den int-Wert von enum in C #

1823

Ich habe eine Klasse namens Questions(Plural). In dieser Klasse gibt es eine Aufzählung namens Question(Singular), die so aussieht.

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

In der QuestionsKlasse habe ich eine get(int foo)Funktion, die ein QuestionsObjekt dafür zurückgibt foo. Gibt es eine einfache Möglichkeit, den ganzzahligen Wert aus der Aufzählung zu entfernen, damit ich so etwas tun kann Questions.Get(Question.Role)?

Jim
quelle
11
Ich weiß, dass ich zu spät zur Party komme, aber anstatt Ihre Methode so zu definieren, wie get(int foo)Sie sie definieren können, und get(Question foo)dann Ihr Casting innerhalb der Methode durchzuführen, können Sie Ihre Methode alsQuestions.Get(Question.Role)
Joe

Antworten:

2353

Wirf einfach die Aufzählung, z

int something = (int) Question.Role;

Das Obige funktioniert für die überwiegende Mehrheit der Aufzählungen, die Sie in freier Wildbahn sehen, da der zugrunde liegende Standardtyp für eine Aufzählung lautet int.

Wie Cecilphillip jedoch betont, können Aufzählungen unterschiedliche zugrunde liegende Typen haben. Wenn eine Aufzählung als , oder deklariert uintist long, ulongsollte sie in den Typ der Aufzählung umgewandelt werden. zB für

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

du solltest benutzen

long something = (long)StarsInMilkyWay.Wolf424B;
Tetraneutron
quelle
23
@ Harry ist es nicht wahr. Sie können eine Aufzählung ohne Casting erstellen, dies ist nicht erforderlich. und ich weise die Nummer nur in besonderen Fällen zu, meistens lasse ich sie als Standardwert. aber Sie können tun enum Test { Item = 1 }und sehen, dass 1 == (int)Test.Itemdas gleich ist.
Jaider
33
@Jaider (int)Test.ItemDas ist eine Besetzung! () ist der explizite Cast-Operator.
Sinthia V
48
@ Sinthia V er sagte, Sie können es ohne Casting erstellen , was richtig ist
Paul Ridgway
7
Wenn der zugrunde liegende Typ für enum Questionnicht war, intaber longdiese Umwandlung den RoleIntegralwert abschneidet !
Quaylar
1
Wenn Sie a Enumals Parameter akzeptieren , wissen Sie, dass Sie nur eine feste Anzahl möglicher Integralwerte erhalten können. Wenn Sie dagegen einfach eine nehmen int, müssen Sie überprüfen, ob diese intinnerhalb der akzeptierten Werte liegt, was den Code kompliziert. Sie können Ihre Signaturen jederzeit überschreiben, z. B. `` `public void MyMethod (int x) {// etwas mit x tun} public void MyMethod (Enum x) {this.MyMethod ((int) x); } `` ``
Percebus
307

Da Aufzählungen jeder integraler Typ sein können ( byte, int, short, usw.), eine robustere Art und Weise den zugrunde liegenden Integralwert des Enum zu bekommen wäre die Verwendung der machen GetTypeCodeMethode in Verbindung mit der ConvertKlasse:

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

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

Dies sollte unabhängig vom zugrunde liegenden Integraltyp funktionieren.

Cecilphillip
quelle
32
Diese Technik hat sich für mich bewährt, wenn es um einen generischen Typ ging, bei dem T: enum (eigentlich T: struct, IConvertible, aber das ist eine andere Geschichte).
aboy021
1
Wie würden Sie dies ändern, um den hexadezimalen Wert der Seite auszudrucken? Dieses Beispiel zeigt den Dezimalwert. Das Problem ist, dass vares vom Typ ist object, also müssen Sie es entpacken und es wird unordentlicher als ich es gerne hätte.
Mark Lakata
2
Ich denke , Sie sollten das Beispiel ändern , object val = Convert...etcdie varin Ihrem Beispiel werden es immer sein object.
Mesh
2
@ TimAbell Alles, was ich wirklich sagen kann, ist, dass wir festgestellt haben, dass dynamisch kompilierte Aspx-Seiten (auf denen Sie die CS-Dateien auf dem Live-Server bereitstellen müssen) die Ganzzahlen jedem Wert unterschiedlich zuweisen. Das bedeutete, dass serialisierte Objekte auf einer Maschine mit unterschiedlichen Werten auf einer anderen Maschine deserialisierten und effektiv beschädigt wurden (was zu stundenlanger Verwirrung führte). Wir haben es mit MS angesprochen, und ich erinnere mich, dass sie sagten, dass die automatisch generierten Ganzzahlen nicht garantiert gleich waren, wenn sie über verschiedene Framework-Versionen hinweg erstellt wurden.
NickG
4
@TimAbell Bei einer anderen Gelegenheit hat ein Entwickler einen veralteten / nicht verwendeten Enum-Wert gelöscht, wodurch alle anderen Werte in der Sequenz um eins überschritten wurden. Daher verlangen unsere Codierungsstandards jetzt, dass IDs immer explizit angegeben werden. Andernfalls werden durch Hinzufügen / Löschen oder sogar automatisches Formatieren des Codes (z. B. alphabetische Sortierung) alle Werte geändert, die zu Datenbeschädigungen führen. Ich würde jedem dringend empfehlen, alle Enum-Ganzzahlen explizit anzugeben. Dies ist äußerst wichtig, wenn sie mit extern (in der Datenbank) gespeicherten Werten korrelieren.
NickG
199

Deklarieren Sie es als statische Klasse mit öffentlichen Konstanten:

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

Und dann können Sie darauf verweisen Question.Role, und es wird immer zu einem intoder was auch immer Sie es definieren ausgewertet .

PablosBicicleta
quelle
31
Ich würde verwenden, static readonly intweil Konstanten in ihre harten Werte kompiliert werden. Siehe stackoverflow.com/a/755693/492
CAD-
96
Diese Lösung bietet tatsächlich nicht den wirklichen Vorteil stark typisierter Aufzählungen. Wenn ich beispielsweise nur einen GameState-enum-Parameter an eine bestimmte Methode übergeben wollte, sollte der Compiler mir nicht erlauben, eine int-Variable als Parameter zu übergeben.
thgc
12
@CADBloke, genau deshalb würden Sie verwenden constund nicht, static readonlyweil Sie bei jedem Vergleich static readonlyeinen Methodenaufruf durchführen, um den Wert der Variablen abzurufen , während Sie mit a constzwei Werttypen direkt vergleichen.
Blockloop
3
@ brettof86 Ja, eine Konstante wäre schneller, wenn die Kompilierungsbeschränkung niemals ein Problem darstellt, ist alles gut.
CAD Kerl
2
@Zack Ich habe das nicht sehr gut erklärt, damit compilation limitationmeine ich, dass der Wert beim Kompilieren fest codiert ist, sodass für jede Änderung dieses Werts alle Assemblys, die ihn verwenden, neu kompiliert werden müssen. Ich bin geneigt, Ihnen in Bezug auf die Verwendung zuzustimmen, da eine Änderung der Werte weitreichende Auswirkungen hätte.
CAD Kerl
87
Question question = Question.Role;
int value = (int) question;

Wird dazu führen value == 2.

jerryjvl
quelle
34
Die Frage nach der temporären Variablen ist nicht erforderlich.
Gishu
1
Also so etwas wie Questions.Get (Convert.ToInt16 (Question.Applications))
Jim
6
Sie können einfach in beide Richtungen werfen; Das einzige, was zu beachten ist, ist, dass Aufzählungen nichts erzwingen (der Aufzählungswert könnte 288 sein, obwohl mit dieser Zahl keine Frage existiert)
Marc Gravell
@jim: Nein, wirf einfach den Wert um: Questions.Get ((int) Question.Applications);
Guffa
1
@Gishu Man könnte sagen, es ist ... fraglich. ;)
Felix D.
79

In einem verwandten Hinweis, wenn Sie den intWert von erhalten möchten System.Enum, dann ehier angegeben:

Enum e = Question.Role;

Sie können verwenden:

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

Die letzten beiden sind einfach hässlich. Ich bevorzuge den ersten.

nawfal
quelle
1
Der zweite ist der schnellste.
Johan B
1
Als jemand, der es gewohnt ist, Mixins im Minecraft-Modding zu verwenden, scheint der zweite der offensichtliche Gewinner zu sein.
Sollace
40

Es ist einfacher als Sie denken - eine Aufzählung ist bereits eine int. Es muss nur daran erinnert werden:

int y = (int)Question.Role;
Console.WriteLine(y); // Prints 2
Michael Petrotta
quelle
15
Nitpick: Diese Aufzählung ist bereits eine int. Andere Aufzählungen können andere Typen sein - versuchen Sie "enum SmallEnum: Byte {A, B, C}"
mqp
9
Absolut wahr. C # -Referenz: "Jeder Aufzählungstyp hat einen zugrunde liegenden Typ, der ein beliebiger ganzzahliger Typ außer char sein kann."
Michael Petrotta
33

Beispiel:

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

Und im Code dahinter, um den Aufzählungswert zu erhalten:

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

oder

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

Aufzählungen werden um 1 erhöht, und Sie können den Startwert festlegen. Wenn Sie den Startwert nicht einstellen, wird er zunächst als 0 zugewiesen.

Peter Mortensen
quelle
6
Kompiliert das tatsächlich?
Peter Mortensen
Kann etwas, das ein Raj ist, auch ein Rahul oder ein Priyanka sein? Ihre Werte stehen in Konflikt und sollten sich verdoppeln, um eindeutig zu sein, z. B. 0, 1, 2, 4, 8 usw. Dies ist mein Hauptanliegen bei Aufzählungen.
Timothy Gonzalez
@ TimothyGonzalez tatsächlich Aufzählungen zählen einfach 1 hoch, wenn Sie ihren Wert nicht explizit angeben;)
derHugo
@derHugo das hängt davon ab, ob Sie die numerischen Werte als Basis 10 oder Basis 2 annehmen.
Timothy Gonzalez
@TimothyGonzalez gut es nicht viel zu übernehmen ... Ich weise darauf hin , nur , dass sie standardmäßig zählen bis nur 1in intaußer Sie nicht ausdrücklich anders definiert
derHugo
28

Ich habe kürzlich von der Verwendung von Aufzählungen in meinem Code auf die Verwendung von Klassen mit geschützten Konstruktoren und vordefinierten statischen Instanzen umgestellt (dank Roelof - C # Sicherstellen gültiger Aufzählungswerte - Zukunftssichere Methode ).

In Anbetracht dessen würde ich im Folgenden näher auf dieses Problem eingehen (einschließlich der impliziten Konvertierung nach / von 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)
}

Der Vorteil dieses Ansatzes besteht darin, dass Sie alles, was Sie hätten, aus der Aufzählung erhalten, aber Ihr Code ist jetzt viel flexibler. Sollten Sie also verschiedene Aktionen basierend auf dem Wert von ausführen müssen Question, können Sie Logik in sich Questionselbst einfügen (dh in der bevorzugten OO) Mode) im Gegensatz zu vielen case-Anweisungen in Ihrem Code, um jedes Szenario anzugehen.


NB: Antwort aktualisiert am 27.04.2018, um die C # 6-Funktionen zu nutzen. dh Deklarationsausdrücke und Lambda-Ausdruckskörperdefinitionen. Siehe Revisionsverlauf für Original - Code. Dies hat den Vorteil, dass die Definition etwas weniger ausführlich ist. Dies war eine der Hauptbeschwerden über den Ansatz dieser Antwort.

JohnLBevan
quelle
2
Ich denke, es ist der Kompromiss zwischen expliziter Besetzung und dem Code, den Sie schreiben müssen, um ihn zu umgehen. Ich liebe die Implementierung immer noch und wünschte nur, sie wäre nicht so langwierig. +1
Lankymart
3
Ich habe verschiedene Arten von Klassen verwendet, die ähnlich aufgebaut sind. Ich finde, sie wirken Wunder, wenn ich versuche, der Methode "Lass mich später kein Idiot sein" zu folgen.
James Haug
20

Wenn Sie eine Ganzzahl für den Enum-Wert erhalten möchten, der in einer Variablen gespeichert ist, für die der Typ wäre Question, um ihn beispielsweise in einer Methode zu verwenden, können Sie dies einfach tun, den ich in diesem Beispiel geschrieben habe:

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

Dadurch wird der Fenstertitel in 4 geändert, da die Variable Geselecteerdlautet Talen.Nederlands. Wenn ich es in ändere Talen.Portugeesund die Methode erneut aufrufe, ändert sich der Text in 3.

Mathijs Van Der Slagt
quelle
3
Codierung in Niederländisch. Ach je.
WiseStrawberry
Leider führt dieser Ansatz zu einer schlechten Leistung, je mehr Sie ihn verwenden. Ich habe es in einem meiner Codes versucht, und im Laufe der Zeit wurde meine Anwendung immer langsamer, mit immer weniger CPU-Auslastung. Dies implizierte, dass die Threads auf etwas warteten - ich gehe von einer Art Garbage Collection aus, möglicherweise weil der Parameter enum auf ToInt32 () gesetzt wurde. Durch den Wechsel zu einem einfachen int.Parse () konnte ich diese schlechte Leistung vollständig beseitigen, und die Leistung blieb gleich, egal wie lange der Code lief.
Greg
16

Um sicherzustellen, dass ein Aufzählungswert vorhanden ist, und ihn dann zu analysieren, können Sie auch Folgendes tun.

// 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
quelle
14

Vielleicht habe ich es verpasst, aber hat jemand eine einfache generische Erweiterungsmethode ausprobiert?

Das funktioniert gut für mich. Sie können die Typumwandlung in Ihrer API auf diese Weise vermeiden, aber letztendlich führt dies zu einer Änderungstypoperation. Dies ist ein guter Fall für die Programmierung von Roslyn , damit der Compiler eine GetValue <T> -Methode für Sie erstellt.

    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
quelle
Möglicherweise, weil (int) customFlag weniger rundum tippt und mehr oder weniger dasselbe tut?
Tim Keating
Betreff "Vielleicht habe ich es verpasst, aber hat jemand eine einfache generische Erweiterungsmethode ausprobiert ?" : SixOThree sagte "Verwenden Sie stattdessen eine Erweiterungsmethode " und Bronek sagte "Sie können dies tun, indem Sie eine Erweiterungsmethode für Ihren definierten Aufzählungstyp implementieren " .
Peter Mortensen
13

Noch eine Möglichkeit:

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

Es wird ergeben:

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

... ist eine schöne Erklärung.

Sie müssen das Ergebnis wie folgt in int umwandeln:

int Question = (int)QuestionType.Role

Ansonsten ist der Typ noch QuestionType .

Diese Strenge ist der C # -Weg.

Eine Alternative besteht darin, stattdessen eine Klassendeklaration zu verwenden:

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
}

Es ist weniger elegant zu deklarieren, aber Sie müssen es nicht in Code umwandeln:

int Question = QuestionType.Role

Alternativ können Sie sich mit Visual Basic wohler fühlen, das diese Art von Erwartung in vielen Bereichen erfüllt.

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

numbersollte den Wert haben 2.

JaimeArmenta
quelle
GetHashCode ist eine Möglichkeit, Wert von Enum Common Mask zu erhalten
ThanhLD
Beachten Sie, dass dies nur „echt“ ist bool*, byte, ushort, int, und uint**. Der GetHashCode für andere Typen ändert den Wert, z. B. einige Bitverschiebungen und Xors. (* 1/0, ** natürlich auf int gegossen). Aber alles in allem tun Sie dies nur, wenn es sich um Ihren eigenen privaten Code handelt.
AnorZaken
10

Sie können dies tun, indem Sie eine Erweiterungsmethode für Ihren definierten Aufzählungstyp implementieren :

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

Dies vereinfacht das Abrufen des int-Werts des aktuellen Aufzählungswerts:

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

oder

int value = Question.Role.getNumberValue();
Bronek
quelle
5
Bronek, Sie haben eine nicht informative Syntax durch eine (übrigens nicht generische) Erweiterungsmethode erstellt, deren Schreiben tatsächlich länger dauert. Ich verstehe nicht, wie es besser ist als die ursprüngliche Lösung von Tetraneutron. Lassen Sie uns dies nicht zu einem Chat machen, Hilfe ist im Stackoverflow immer willkommen und jeder hier ist hier, um zu helfen. Bitte nehmen Sie meinen Kommentar als konstruktive Kritik.
Benjamin Gruenbaum
2
Benjamin, zuallererst, warum hast du meinen Kommentar gelöscht? Ich verstehe deine Entscheidungen nicht - vielleicht würde jemand anderes in der Community meinem Kommentar zustimmen. Zweitens schließt meine Lösung die von Tetraneutron ein und genau ist es einfacher und weniger zu schreiben, weil eine Die Erweiterungsmethode wird von IntelliSense vorgeschlagen. Ich denke, Ihre Entscheidung ist nicht unparteiisch und repräsentativ. Ich sehe viele ähnliche Antworten auf Stack und es ist in Ordnung. Trotzdem verwende ich meine Lösung und vielleicht gibt es einige Leute, die meine Lösung in Zukunft wählen würden, aber Diese negativen Punkte erschweren das Auffinden. Vor allem ist es korrekt und nicht kopiert.
Bronek
3
@Bronek Wenn du mich nicht anrufst, bekomme ich keinen Hinweis darauf, dass du geantwortet hast. Ich habe Ihren Kommentar nicht gelöscht. Ich habe nicht die Fähigkeit oder möchte dies tun. Wahrscheinlich kam ein Mod vorbei und löschte ihn - Sie können ihn gerne für die Aufmerksamkeit des Moderators markieren und fragen, warum oder noch besser - fragen Sie bei Meta Stack Overflow . Ich habe eine Meinung zu Ihrer Lösung vom Standpunkt der Programmierung aus, die vollkommen in meinem Recht liegt - dies ist der Grund, warum Kommentare anfangen sollen, ohne dass Sie sie persönlich nehmen müssen.
Benjamin Gruenbaum
8

Verwenden Sie stattdessen eine Erweiterungsmethode:

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

Und die Verwendung ist etwas hübscher:

var intValue = Question.Role.IntValue();
SixOThree
quelle
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
quelle
Anzug - "10. (Kartenspiele) Jeder Satz eines Kartenspiels, der sich durch Farbe und / oder bestimmte Embleme auszeichnet, wie Spaten, Herzen, Diamanten oder Keulen traditioneller anglo-, hispanischer und französischer Spielkarten."
Peter Mortensen
Eine Erklärung des Beispielcodes wäre angebracht (durch Bearbeiten Ihrer Antwort , nicht hier in den Kommentaren).
Peter Mortensen
Null ist im Allgemeinen für nicht gesetzte / unbekannte Zustände in Aufzählungen reserviert, was ungewöhnlich ist, um es so zu definieren
Chad Grant
6

Verwenden:

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

Es wird dazu führen value == 2 .

Dies gilt nur, wenn die Aufzählung in eine passt int.

GinCanhViet
quelle
1
Dies gilt nur, wenn die Aufzählung intnatürlich GetHashCodein eine passt , da eine ganze Zahl zurückgegeben wird.
RB.
5

Da Aufzählungen mit mehreren primitiven Typen deklariert werden können, kann eine generische Erweiterungsmethode zum Umwandeln eines beliebigen Aufzählungstyps hilfreich sein.

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
quelle
4

Es folgt die Erweiterungsmethode

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
quelle
4

Mein Lieblingshack mit int oder kleineren Aufzählungen:

GetHashCode();

Für eine Aufzählung

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

Diese,

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

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

Ausgänge

one
1
1
max
2147483647
2147483647
min
-2147483648
-2147483648

Haftungsausschluss:

Es funktioniert nicht für lange Aufzählungen.

Erik Karlsson
quelle
3

Die einfachste Lösung, die ich mir vorstellen kann, ist das Überladen der Get(int)Methode wie folgt :

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

wo [modifiers]kann im Allgemeinen das gleiche sein wie für die Get(int)Methode. Wenn Sie die QuestionsKlasse nicht bearbeiten können oder aus irgendeinem Grund nicht möchten, können Sie die Methode überladen, indem Sie eine Erweiterung schreiben:

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

Das Beispiel, das ich vorschlagen möchte, "um einen 'int'-Wert aus einer Aufzählung zu erhalten", ist

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

int answer = (int)Sample.Book;

Jetzt lautet die Antwort 1.

Vivek
quelle
3

Verwenden:

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

Versuchen Sie dies, anstatt enum in int umzuwandeln:

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

In Visual Basic sollte es sein:

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

Private value As Integer = CInt(Question.Role)
VPP
quelle
3
Die Frage ist für C #.
Strg S
2
Der Titel lautet "Get int value from enum in C #" .
Peter Mortensen
0

Ich habe mir diese Erweiterungsmethode ausgedacht, die aktuelle Sprachfunktionen enthält. Durch die Verwendung von dynamic muss ich dies nicht zu einer generischen Methode machen und den Typ angeben, der den Aufruf einfacher und konsistenter hält:

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
quelle
Bitte nein, Sie können dies alles in einer Zeile Convert.Changetype (e, e.GetTypeCode ()) tun und ein Objekt zurückerhalten, ohne dass eine Dynamik oder eine Erweiterungsmethode erforderlich ist
Chad Grant
Ich werde mit der Verwendung von Convert nicht einverstanden sein. Nur eine Besetzung zu verwenden wäre einfacher. Meine Absicht war es, jede Aufzählung ohne Verwendung einer Besetzung in ihren Wert umwandeln zu können. Dies ermöglicht das Ändern des Aufzählungstyps, ohne dass alle zugehörigen Besetzungen geändert werden müssen - aber wann geschieht dies?. Die Erweiterungsmethode funktioniert ordnungsgemäß. Ich habe jedoch ein Problem damit, dass der Complier, da er dynamisch ist, keine Typprüfung durchführen kann (anscheinend für die gesamte Anweisung), was bedeutet, dass die Typprüfung beim Ausführen erfolgt - keine gute Lösung. Ich denke, ich werde zu den Casts zurückkehren.
Jeff
1
Ich habe nicht gesagt, dass es übergossen werden soll, nur dass dieser Code unsinnig ist und nichts bewirkt, was das Problem tatsächlich verschlimmert. Ich würde empfehlen, diese Lösung zu entfernen
Chad Grant