634 Stimmen

Assoziieren von Enums mit Strings in C#

Ich weiß, dass das Folgende nicht möglich ist, weil der Typ der Aufzählung ein int sein muss

enum GroupTypes
{
    TheGroup = "OEM",
    TheOtherGroup = "CMB"
}

In meiner Datenbank erhalte ich ein Feld mit unverständlichen Codes (die OEM y CMB s). Ich möchte dieses Feld zu einem enum oder etwas anderes Verständliches. Denn wenn das Ziel die Lesbarkeit ist, sollte die Lösung prägnant sein.

Welche anderen Möglichkeiten habe ich?

1 Stimmen

Mögliche Duplikate von Enum ToString

24 Stimmen

Ich bin mir nicht sicher, warum die meisten Antworten nicht einfach "const string" verwenden und stattdessen eigene Klassen erstellen.

2 Stimmen

Sie können zwar keine Zeichenketten verwenden, aber Sie können sehr wohl Zeichenketten verwenden. Das ist eine Option, wenn Sie Werte mit nur einem Buchstaben verwenden können.

46voto

Arthur C Punkte 530

Das ist eigentlich ganz einfach. Verwenden Sie den folgenden Code.

enum GroupTypes
{
   OEM,
   CMB
};

Wenn Sie dann den String-Wert jedes Enum-Elements abrufen möchten, verwenden Sie einfach die folgende Codezeile.

String oemString = Enum.GetName(typeof(GroupTypes), GroupTypes.OEM);

Ich habe diese Methode erfolgreich in der Vergangenheit verwendet, und ich habe auch eine Konstanten-Klasse verwendet, um String-Konstanten zu halten, beide funktionieren ziemlich gut, aber ich neige dazu, dies zu bevorzugen.

36voto

casperOne Punkte 72238

Sie können den Elementen in der Aufzählung Attribute hinzufügen und dann die Reflexion verwenden, um die Werte aus den Attributen zu erhalten.

Sie müssen den "Feld"-Spezifizierer verwenden, um die Attribute anzuwenden, etwa so:

enum GroupTypes
{
    [field:Description("OEM")]
    TheGroup,

    [field:Description("CMB")]
    TheOtherGroup
}

Sie würden dann über die statischen Felder des Typs der Aufzählung (in diesem Fall GroupTypes) reflektieren und die DescriptionAttribute für den Wert, den Sie mit Hilfe von Reflexion gesucht haben:

public static DescriptionAttribute GetEnumDescriptionAttribute<T>(
    this T value) where T : struct
{
    // The type of the enum, it will be reused.
    Type type = typeof(T);

    // If T is not an enum, get out.
    if (!type.IsEnum) 
        throw new InvalidOperationException(
            "The type parameter T must be an enum type.");

    // If the value isn't defined throw an exception.
    if (!Enum.IsDefined(type, value))
        throw new InvalidEnumArgumentException(
            "value", Convert.ToInt32(value), type);

    // Get the static field for the value.
    FieldInfo fi = type.GetField(value.ToString(), 
        BindingFlags.Static | BindingFlags.Public);

    // Get the description attribute, if there is one.
    return fi.GetCustomAttributes(typeof(DescriptionAttribute), true).
        Cast<DescriptionAttribute>().SingleOrDefault();
}

Ich habe mich für die Rückgabe der DescriptionAttribute selbst, falls Sie feststellen wollen, ob das Attribut überhaupt angewendet wird oder nicht.

16voto

C. Ross Punkte 29783

Verwenden Sie eine Klasse.

Edit: Besseres Beispiel

class StarshipType
{
    private string _Name;
    private static List<StarshipType> _StarshipTypes = new List<StarshipType>();

    public static readonly StarshipType Ultralight = new StarshipType("Ultralight");
    public static readonly StarshipType Light = new StarshipType("Light");
    public static readonly StarshipType Mediumweight = new StarshipType("Mediumweight");
    public static readonly StarshipType Heavy = new StarshipType("Heavy");
    public static readonly StarshipType Superheavy = new StarshipType("Superheavy");

    public string Name
    {
        get { return _Name; }
        private set { _Name = value; }
    }

    public static IList<StarshipType> StarshipTypes
    {
        get { return _StarshipTypes; }
    }

    private StarshipType(string name, int systemRatio)
    {
        Name = name;
        _StarshipTypes.Add(this);
    }

    public static StarshipType Parse(string toParse)
    {
        foreach (StarshipType s in StarshipTypes)
        {
            if (toParse == s.Name)
                return s;
        }
        throw new FormatException("Could not parse string.");
    }
}

15voto

Dave Van den Eynde Punkte 16711

Erstellen Sie eine zweite Aufzählung für Ihre DB, die Folgendes enthält:

enum DBGroupTypes
{
    OEM = 0,
    CMB = 1
}

Jetzt können Sie Enum.Parse verwenden, um den richtigen DBGroupTypes-Wert aus den Zeichenketten "OEM" und "CMB" abzurufen. Anschließend können Sie diese in int umwandeln und die richtigen Werte aus der richtigen Aufzählung abrufen, die Sie in Ihrem Modell weiter verwenden möchten.

14voto

Luis Orantes Punkte 345

Eine andere Möglichkeit, mit dem Problem umzugehen, besteht darin, eine Aufzählung und ein Array von Strings zu haben, das die Aufzählungswerte mit der Liste der Strings abbildet:

public enum GroupTypes
{
    TheGroup  = 0,
    TheOtherGroup 
}

string[] GroupTypesStr = {
    "OEM",
    "CMB"
};

können Sie es etwa so verwenden:

Log.Write(GroupTypesStr[(int)GroupTypes.TheOtherGroup]);

Sie wird CMB auffordern

PROS:

  1. Einfacher und sauberer Code.
  2. High Performance (insbesondere im Vergleich zu den Ansätzen, die Klassen verwenden)

CONS:

  1. Bei der Bearbeitung der Liste kann es zu Problemen kommen, aber für eine kurze Liste.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X