Freigeben über


Verwenden von Enumerationsklassen anstelle von Enumerationstypen

Tipp

Dieser Inhalt ist ein Auszug aus dem eBook .NET Microservices Architecture for Containerized .NET Applications, verfügbar auf .NET Docs oder als kostenlose herunterladbare PDF, die offline gelesen werden kann.

.NET Microservices-Architektur für containerisierte .NET-Anwendungen eBook-Cover-Thumbnail.

Enumerationen (oder Enumerationstypen kurz) sind ein dünner Sprachwrapper um einen integralen Typ. Möglicherweise möchten Sie deren Verwendung einschränken, wenn Sie einen Wert aus einem geschlossenen Wertesatz speichern. Die Klassifizierung basiert auf Größen (klein, mittel, groß) ist ein gutes Beispiel. Das Verwenden von Enumerationen zur Ablaufsteuerung oder für robustere Abstraktionen kann zu schlecht strukturiertem Code führen. Diese Art der Verwendung führt zu zerbrechlichem Code mit vielen Kontrollflussanweisungen, die Werte des Enums überprüfen.

Stattdessen können Sie Enumerationsklassen erstellen, die alle umfangreichen Features einer objektorientierten Sprache ermöglichen.

Dies ist jedoch kein kritisches Thema, und in vielen Fällen können Sie weiterhin reguläre Enum-Typen verwenden, wenn dies Ihre Vorliebe ist. Die Verwendung von Enumerationsklassen bezieht sich eher auf geschäftsbezogene Konzepte.

Implementieren einer Enumerationsbasisklasse

Der Bestell-Microservice in eShopOnContainers stellt eine Beispielimplementierung der Enumerationsbasisklasse bereit, wie im folgenden Beispiel gezeigt:

public abstract class Enumeration : IComparable
{
    public string Name { get; private set; }

    public int Id { get; private set; }

    protected Enumeration(int id, string name) => (Id, Name) = (id, name);

    public override string ToString() => Name;

    public static IEnumerable<T> GetAll<T>() where T : Enumeration =>
        typeof(T).GetFields(BindingFlags.Public |
                            BindingFlags.Static |
                            BindingFlags.DeclaredOnly)
                 .Select(f => f.GetValue(null))
                 .Cast<T>();

    public override bool Equals(object obj)
    {
        if (obj is not Enumeration otherValue)
        {
            return false;
        }

        var typeMatches = GetType().Equals(obj.GetType());
        var valueMatches = Id.Equals(otherValue.Id);

        return typeMatches && valueMatches;
    }

    public int CompareTo(object other) => Id.CompareTo(((Enumeration)other).Id);

    // Other utility methods ...
}

Sie können diese Klasse als Typ in einem beliebigen Entitäts- oder Wertobjekt verwenden, wie für die folgende CardType Klasse: Enumeration

public class CardType
    : Enumeration
{
    public static CardType Amex = new(1, nameof(Amex));
    public static CardType Visa = new(2, nameof(Visa));
    public static CardType MasterCard = new(3, nameof(MasterCard));

    public CardType(int id, string name)
        : base(id, name)
    {
    }
}

Weitere Ressourcen