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.

2voto

Bryan Rowe Punkte 8987

Ich würde es zu einer Klasse machen und eine Aufzählung ganz vermeiden. Und dann mit der Verwendung eines Typehandlers könnten Sie das Objekt erstellen, wenn Sie es aus der Datenbank holen.

IE:

public class Group
{
    public string Value{ get; set; }
    public Group( string value ){ Value = value; } 
    public static Group TheGroup() { return new Group("OEM"); }
    public static Group OtherGroup() { return new Group("CMB"); }

}

2voto

Siavash Mortazavi Punkte 817

Ich wollte die Verwendung von String-Literalen vollständig vermeiden, und außerdem brauchte ich keine Leerzeichen in den Artikelbeschreibungen. Vor allem wollte ich einen Mechanismus haben, um zu prüfen, ob die angegebene Zeichenkette ein gültiges Element ist, also habe ich diese Lösung gefunden:

public class Seasons
{
    public static string Spring { get; }
    public static string Summer { get; }
    public static string Fall { get; }
    public static string Winter { get; }

    public static bool IsValid(string propertyName)
    {
        if (string.IsNullOrEmpty(propertyName))
        {
            return false;
        }

        try
        {           
            return typeof(Seasons).GetProperty(propertyName) != null;
        }
        catch
        {
            return false;
        }       
    }
}

Und so funktioniert es:

void Main()
{
    string s = nameof(Seasons.Fall);
    Console.WriteLine($"Fall is valid: {Seasons.IsValid(s)}"); // true

    s = "WrongSeason";
    Console.WriteLine($"WrongSeason is valid: {Seasons.IsValid(s)}"); // false
}

Ich habe versucht, IsValid() in eine Basisklasse umzuwandeln und Reflection zu verwenden, um den Typ zu lesen (MethodBase.GetCurrentMethod().DeclaringType), aber da ich es statisch haben wollte, gibt es den Typ der Basisklasse zurück, nicht den geerbten Typ. Ich würde mich freuen, wenn Sie hier Abhilfe schaffen könnten! Hier ist, was ich zu erreichen versuchte:

public  class Seasons : ConstantStringsBase
{
    // ... same
}

public  class ConstantStringsBase
{
    public static bool IsValid(string propertyName)
    {       
        return MethodBase.GetCurrentMethod().DeclaringType.GetProperty(propertyName) != null;
    }
}

2voto

dmihailescu Punkte 1515

Wenn ich das richtig verstehe, brauchen Sie eine Konvertierung von String zu Enum:

enum GroupTypes {
    Unknown = 0,
    OEM = 1,
    CMB = 2
}
static GroupTypes StrToEnum(string str){
    GroupTypes g = GroupTypes.Unknown;
    try {
        object o = Enum.Parse(typeof(GroupTypes), str, true);
        g = (GroupTypes)(o ?? 0);
    } catch {
    }
    return g;
}
// then use it like this
GroupTypes g1 = StrToEnum("OEM");
GroupTypes g2 = StrToEnum("bad value");

Wenn Sie möchten, können Sie den Enum-Typ mit Generika aufpeppen.

1voto

toddmo Punkte 18450

Sie können zwei Enums verwenden. Eine für die Datenbank und die andere für die Lesbarkeit.

Man muss nur dafür sorgen, dass sie synchron bleiben, und das scheint ein geringer Aufwand zu sein. Sie müssen die Werte nicht festlegen, sondern nur die Positionen gleich setzen, aber durch das Festlegen der Werte wird deutlich, dass die beiden Enums miteinander verbunden sind, und es werden Fehler durch das Umordnen der Enum-Mitglieder verhindert. Und ein Kommentar lässt das Wartungsteam wissen, dass diese zusammenhängen und synchron gehalten werden müssen.

// keep in sync with GroupTypes
public enum GroupTypeCodes
{
    OEM,
    CMB
}

// keep in sync with GroupTypesCodes
public enum GroupTypes
{
    TheGroup = GroupTypeCodes.OEM,
    TheOtherGroup = GroupTypeCodes.CMB
}

Um ihn zu verwenden, müssen Sie ihn zunächst in den Code umwandeln:

GroupTypes myGroupType = GroupTypes.TheGroup;
string valueToSaveIntoDatabase = ((GroupTypeCodes)myGroupType).ToString();

Wenn Sie es noch bequemer machen wollen, können Sie eine Erweiterungsfunktion hinzufügen, die nur für diese Art von Enum funktioniert:

public static string ToString(this GroupTypes source)
{
    return ((GroupTypeCodes)source).ToString();
}

und Sie können dann einfach tun:

GroupTypes myGroupType = GroupTypes.TheGroup;
string valueToSaveIntoDatabase = myGroupType.ToString();

1voto

nyconing Punkte 1065

Hinzufügen dieser Klasse

public class DatabasePreference {
    public DatabasePreference([CallerMemberName] string preferenceName = "") {
        PreferenceName = preferenceName;
    }
    public string PreferenceName;
}

Diese Arbeit verwendet CallerMemberName um die Kodierung zu minimieren

Verwenden:

//Declare names
public static DatabasePreference ScannerDefaultFlashLight = new DatabasePreference();
public static DatabasePreference ScannerQrCodes = new DatabasePreference();
public static DatabasePreference Scanner1dCodes = new DatabasePreference();

Testen Sie es:

Console.WriteLine(ScannerDefaultFlashLight.PreferenceName);
Console.WriteLine(ScannerDefaultFlashLight.Scanner1dCodes);

Ausgabe:

ScannerDefaultFlashLight
Scanner1dCodes

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