it-swarm.com.de

Int-Wert aus Enum in C # abrufen

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 Klasse Questions habe ich eine Funktion get(int foo), die ein Objekt Questions für dieses Objekt foo zurückgibt. Gibt es eine einfache Möglichkeit, den ganzzahligen Wert aus der Aufzählung abzurufen, damit ich etwas wie Questions.Get(Question.Role) ausführen kann?

1634
jim

Wirf einfach die Aufzählung, z.

int something = (int) Question.Role;

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

Wie jedoch cecilphillip hervorhebt, können Aufzählungen unterschiedliche zugrunde liegende Typen haben. Wenn eine Aufzählung als uint, long oder ulong deklariert wird, sollte sie in den Typ der Aufzählung umgewandelt werden. z.B. zum

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

du solltest benutzen

long something = (long)StarsInMilkyWay.Wolf424B;
2126
Tetraneutron

Da Aufzählungen ein beliebiger ganzzahliger Typ sein können (byte, int, short usw.), wäre es eine robustere Möglichkeit, den zugrunde liegenden ganzzahligen Wert der Aufzählung zu ermitteln, die zu verwenden GetTypeCode -Methode in Verbindung mit der Convert -Klasse:

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.

281
cecilphillip

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 es als Question.Role referenzieren, und es wird immer als int ausgewertet, oder als was auch immer Sie es definieren.

181
PablosBicicleta
Question question = Question.Role;
int value = (int) question;

Wird zu value == 2 führen.

80
jerryjvl

Wenn Sie den Wert int von System.Enum erhalten möchten, geben Sie e hier ein:

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.

70
nawfal

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

int y = (int)Question.Role;
Console.WriteLine(y); // prints 2
37

Beispiel:

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

Und im Code dahinter, um den Wert der Aufzählung zu erhalten:

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

oder

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

Die Aufzählungen werden um 1 erhöht, und Sie können den Startwert festlegen. Wenn Sie den Startwert nicht einstellen, wird dieser zunächst mit 0 belegt.

27
sooraj

Ich habe kürzlich darauf verzichtet, in meinem Code Aufzählungen zu verwenden, anstatt Klassen mit geschützten Konstruktoren und vordefinierten statischen Instanzen zu verwenden (dank Roelof - C # Gültige Aufzählungswerte sicherstellen - Zukunftssichere Methode ).

In Anbetracht dessen gehe ich wie folgt mit diesem Problem um (einschließlich der impliziten Konvertierung in/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 ist, dass Sie alles aus der Aufzählung erhalten, aber Ihr Code jetzt viel flexibler ist. Sollten Sie also verschiedene Aktionen basierend auf dem Wert von Question ausführen müssen, können Sie die Logik in Question selbst (dh in der bevorzugten OO Weise), anstatt viele case-Anweisungen in Ihrem Code zu platzieren, um jedes Szenario anzugehen.


NB: Die Antwort wurde am 27.04.2018 aktualisiert, um die Funktionen von C # 6 nutzen zu können. d.h. Deklarationsausdrücke und Lambda-Ausdruckskörperdefinitionen. Siehe Änderungshistorie für den Originalcode. Dies hat den Vorteil, dass die Definition etwas weniger ausführlich ist. Das war eine der Hauptbeschwerden über den Ansatz dieser Antwort.

23
JohnLBevan

Wenn Sie eine Ganzzahl für den in einer Variablen gespeicherten Aufzählungswert abrufen möchten, dessen Typ Question ist, um ihn beispielsweise in einer Methode zu verwenden, können Sie dies einfach tun, das 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 GeselecteerdTalen.Nederlands ist. Wenn ich es in Talen.Portugees ändere und die Methode erneut aufrufe, ändert sich der Text in 3.

Es fiel mir schwer, diese einfache Lösung im Internet zu finden, und ich konnte sie nicht finden. Deshalb testete ich etwas und fand es heraus. Hoffe das hilft. ;)

17

Um sicherzustellen, dass ein Aufzählungswert vorhanden ist, und ihn dann zu analysieren, können Sie auch folgendermaßen vorgehen.

// 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() + ".");

Ich hoffe das hilft.

14
Nathon

Vielleicht habe ich es verpasst, aber jemand hat 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 Operation zum Ändern des Typs. Dies ist ein guter Fall, um Roselyn so zu programmieren, dass der Compiler eine GetValue-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;
    }
}    
12
Doug
public enum QuestionType
{
    Role = 2,
    ProjectFunding = 3,
    TotalEmployee = 4,
    NumberOfServers = 5,
    TopBusinessConcern = 6
}

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

Sie müssen das Ergebnis auf int wie folgt umsetzen:

int Question = (int)QuestionType.Role

Ansonsten ist der Typ immer noch QuestionType.

Diese Strenge ist die C # -Methode.

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 in vielen Bereichen dieser Art von Erwartung gerecht wird.

11

Ein weiterer Weg, es zu tun:

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

Wird darin enden, dass:

Name: Role, Value: 2
11
plavozont
int number = Question.Role.GetHashCode();

number sollte den Wert 2 haben.

9
JaimeArmenta

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 Enum-Werts:

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

oder

int value = Question.Role.getNumberValue();
8
Bronek

Wie wäre es stattdessen mit einer Erweiterungsmethode:

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

Und die Verwendung ist etwas schöner:

var intValue = Question.Role.IntValue();
7
SixOThree
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 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);
}
4
Gauravsa

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;
}
3
Kamran Shahid

Da Aufzählungen mit mehreren primitiven Typen deklariert werden können, kann eine generische Erweiterungsmethode zum Umwandeln eines beliebigen Aufzählungstyps nützlich 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;
3

Mein Lieblings-Hack 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: Funktioniert nicht für Aufzählungen, die auf long basieren

3
Erik Karlsson

Das Beispiel, das ich vorschlagen möchte, um den int-Wert von enum zu erhalten, lautet:

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

int answer = (int)Sample.Book;

jetzt lautet die Antwort 1.

Ich hoffe das könnte jemandem helfen.

2
Vivek

Versuchen Sie dies, anstatt enum in int zu konvertieren:

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

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

dabei kann [modifiers] im Allgemeinen mit Get(int) identisch sein. Wenn Sie die Klasse Questions 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);
    }
}
1
Grx70

Ich bin etwas spät dran, habe mir aber diese Erweiterungsmethode ausgedacht, die die aktuellen Sprachfunktionen enthält. Durch die Verwendung von dynamic muss dies keine generische Methode sein und der Typ angegeben werden, der den Aufruf einfacher und konsistenter macht. Bitte lassen Sie mich wissen, wenn ich etwas falsch gemacht habe:

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

In Vb. Es sollte sein

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

Private value As Integer = CInt(Question.Role)
1
VPP
Question question = Question.Role;
int value = question.GetHashCode();

Wird zu value == 2 führen.

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

0
GinCanhViet