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.

3voto

Mike Punkte 1225

Eine kleine Änderung der Glennular Extension Methode, so dass man die Erweiterung auch für andere Dinge als nur ENUM's verwenden kann;

using System;
using System.ComponentModel;
namespace Extensions {
    public static class T_Extensions {
        /// <summary>
        /// Gets the Description Attribute Value
        /// </summary>
        /// <typeparam name="T">Entity Type</typeparam>
        /// <param name="val">Variable</param>
        /// <returns>The value of the Description Attribute or an Empty String</returns>
        public static string Description<T>(this T t) {
            DescriptionAttribute[] attributes = (DescriptionAttribute[])t.GetType().GetField(t.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
            return attributes.Length > 0 ? attributes[0].Description : string.Empty;
        }
    }
}

Oder Linq verwenden

using System;
using System.ComponentModel;
using System.Linq;

namespace Extensions {

public static class T_Extensions {
        public static string Description<T>(this T t) =>
            ((DescriptionAttribute[])t
            ?.GetType()
            ?.GetField(t?.ToString())
            ?.GetCustomAttributes(typeof(DescriptionAttribute), false))
            ?.Select(a => a?.Description)
            ?.FirstOrDefault() 
            ?? string.Empty;  
    }
}

3voto

Dies ist eine Möglichkeit, sie zu nutzen als ein stark typisierter Parameter oder als eine Zeichenkette :

public class ClassLikeEnum
{
    public string Value
    {
        get;
        private set;
    }

    ClassLikeEnum(string value) 
    {
        Value = value;
    }

    public static implicit operator string(ClassLikeEnum c)
    {
        return c.Value;
    }

    public static readonly ClassLikeEnum C1 = new ClassLikeEnum("RandomString1");
    public static readonly ClassLikeEnum C2 = new ClassLikeEnum("RandomString2");
}

3voto

Reed Copsey Punkte 536986

Meine erste Frage: Haben Sie Zugriff auf die Datenbank selbst? Dies sollte idealerweise in der Datenbank normalisiert werden, da sonst jede Lösung fehleranfällig ist. Meiner Erfahrung nach neigen Datenfelder voller "OEM" und "CMB" dazu, im Laufe der Zeit Dinge wie "oem" und andere "Scheißdaten" zu enthalten.... Wenn Sie die Daten normalisieren können, können Sie den Schlüssel in der Tabelle, die die Elemente enthält, als Ihre Enum verwenden, und schon haben Sie eine viel sauberere Struktur.

Wenn das nicht verfügbar ist, würde ich Ihre Enum machen, und machen Sie eine Klasse, um Ihre Zeichenfolge in die Enum für Sie zu parsen. Dies würde Ihnen zumindest eine gewisse Flexibilität bei der Behandlung von Nicht-Standard-Einträge und viel mehr Flexibilität für Trapping oder Behandlung von Fehlern als tun eine der Workarounds mit Enum.Parse/Reflection/etc. Ein Wörterbuch würde funktionieren, könnte aber zusammenbrechen, wenn Sie jemals Probleme mit Groß- und Kleinschreibung usw. haben.

Ich würde empfehlen, eine Klasse zu schreiben, damit Sie das tun können:

// I renamed this to GroupType, since it sounds like each element has a single type...
GroupType theType = GroupTypeParser.GetGroupType(theDBString);

Dadurch bleibt die Lesbarkeit weitgehend erhalten, ohne dass der DB geändert werden muss.

3voto

user1441126 Punkte 141

C# unterstützt keine enumerierten Strings, aber für die meisten Situationen können Sie eine Liste oder ein Dictionary verwenden, um den gewünschten Effekt zu erzielen.

Z. B. zum Ausdrucken von bestandenen/nicht bestandenen Ergebnissen:

List<string> PassFail = new List<string> { "FAIL", "PASS" };
bool result = true;
Console.WriteLine("Test1: " + PassFail[result.GetHashCode()]);

2voto

Mehrere gute Antworten oben, wenn Sie die Erweiterung selbst programmieren möchten

Ich verwende CodeHelper.Core.Extensions

enum GroupTypes
{

    [StringValue("OEM")] TheGroup,
    [StringValue("CMB")] TheOtherGroup = "CMB"
}

GroupTypes.TheOtherGroup.ToStringValue()

Wenn Sie den Werten kein StringValue-Attribut hinzugefügt haben, gibt die Erweiterung den normalen Namen zurück (.ToTring()) Und super einfach, um Leerzeichen und andere normalerweise nicht erlaubte Zeichen wie Leerzeichen oder den Beginn mit Zahlen hinzuzufügen

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