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.

1voto

ayepiz Punkte 35

Auf der Grundlage anderer Meinungen bin ich zu folgendem Ergebnis gekommen. Dieser Ansatz vermeidet die Eingabe von .Wert, wenn Sie den konstanten Wert erhalten möchten.

Ich habe eine Basisklasse für alle String-Enums wie diese:

using System;
using Newtonsoft.Json;

[JsonConverter(typeof(ConstantConverter))]
public class StringEnum: IConvertible
{
    public string Value { get; set; }

    protected StringEnum(string value)
    {
        Value = value;
    }

    public static implicit operator string(StringEnum c)
    {
        return c.Value;
    }
    public string ToString(IFormatProvider provider)
    {
        return Value;
    }

    public TypeCode GetTypeCode()
    {
        throw new NotImplementedException();
    }

    public bool ToBoolean(IFormatProvider provider)
    {
        throw new NotImplementedException();
    }
    //The same for all the rest of IConvertible methods
}

Der JsonConverter ist wie folgt aufgebaut:

using System;
using Newtonsoft.Json;

class ConstantConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return true;
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value == null)
        {
            serializer.Serialize(writer, null);
        }
        else
        {
            serializer.Serialize(writer, value.ToString());
        }
    }
}

Und ein tatsächliches String-Enum wird etwa so aussehen:

public sealed class Colors : StringEnum
{
    public static Colors Red { get { return new Catalog("Red"); } }
    public static Colors Yellow { get { return new Catalog("Yellow"); } }
    public static Colors White { get { return new Catalog("White"); } }

    private Colors(string value) : base(value) { }
}

Und damit können Sie einfach Color.Red verwenden, um auch ohne die Value-Eigenschaft in Json zu serialisieren

1voto

bohdan_trotsenko Punkte 4915

Ich habe sogar ein paar Enums implementiert, wie von @Even vorgeschlagen (via class X y public static X Mitglieder), nur um später herauszufinden, dass es heutzutage, beginnend mit .Net 4.5, eine das Recht ToString() Methode.

Jetzt bin ich reimplementieren alles zurück zu Enums.

1voto

ThinkBonobo Punkte 13628

Ich war im Grunde auf der Suche nach der Reflection-Antwort von @ArthurC

Um seine Antwort noch ein wenig zu erweitern, kann man es noch besser machen, indem man eine generische Funktion hat:

    // If you want for a specific Enum
    private static string EnumStringValue(GroupTypes e)
    {
        return EnumStringValue<GroupTypes>(e);
    }

    // Generic
    private static string EnumStringValue<T>(T enumInstance)
    {
        return Enum.GetName(typeof(T), enumInstance);
    } 

Dann können Sie einfach einpacken, was Sie haben

EnumStringValue(GroupTypes.TheGroup) // if you incorporate the top part

o

EnumStringValue<GroupTypes>(GroupTypes.TheGroup) // if you just use the generic

0voto

Mahib Punkte 3767

Ich habe etwas Ähnliches gemacht;

public enum BusinessUnits
{
    NEW_EQUIPMENT = 0,
    USED_EQUIPMENT = 1,
    RENTAL_EQUIPMENT = 2,
    PARTS = 3,
    SERVICE = 4,
    OPERATOR_TRAINING = 5
}

public class BusinessUnitService
{
    public static string StringBusinessUnits(BusinessUnits BU)
    {
        switch (BU)
        {
            case BusinessUnits.NEW_EQUIPMENT: return "NEW EQUIPMENT";
            case BusinessUnits.USED_EQUIPMENT: return "USED EQUIPMENT";
            case BusinessUnits.RENTAL_EQUIPMENT: return "RENTAL EQUIPMENT";
            case BusinessUnits.PARTS: return "PARTS";
            case BusinessUnits.SERVICE: return "SERVICE";
            case BusinessUnits.OPERATOR_TRAINING: return "OPERATOR TRAINING";
            default: return String.Empty;
        }
    }
}

Rufen Sie ihn damit an;

BusinessUnitService.StringBusinessUnits(BusinessUnits.PARTS)

0voto

Chad Hedgcock Punkte 10251

Ich brauchte nichts Robustes wie das Speichern der Zeichenfolge in Attributen. Ich brauchte nur etwas zu machen wie MyEnum.BillEveryWeek in "Rechnung jede Woche" oder MyEnum.UseLegacySystem in "use legacy system" umwandeln - also die Aufzählung durch die Camel-Case-Schreibweise in einzelne klein geschriebene Wörter aufteilen.

public static string UnCamelCase(this Enum input, string delimiter = " ", bool preserveCasing = false)
{
    var characters = input.ToString().Select((x, i) =>
    {

       if (i > 0 && char.IsUpper(x))
       {
           return delimiter + x.ToString(CultureInfo.InvariantCulture);
       }
       return x.ToString(CultureInfo.InvariantCulture);

    });

    var result = preserveCasing
       ? string.Concat(characters)
       : string.Concat(characters).ToLower();

    var lastComma = result.LastIndexOf(", ", StringComparison.Ordinal);

    if (lastComma > -1)
    {
       result = result.Remove(lastComma, 2).Insert(lastComma, " and ");
    }

    return result;
}

MyEnum.UseLegacySystem.UnCamelCase() Ausgaben "Altsystem verwenden"

Wenn Sie mehrere Flaggen gesetzt haben, werden diese in einfaches Englisch umgewandelt (kommagetrennt, mit einem "und" anstelle des letzten Kommas).

var myCustomerBehaviour = MyEnum.BillEveryWeek | MyEnum.UseLegacySystem | MyEnum.ChargeTaxes;

Console.WriteLine(myCustomerBehaviour.UnCamelCase());
//outputs "bill every week, use legacy system and charge taxes"

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