Udostępnij za pośrednictwem


Używaj klas wyliczeniowych zamiast typów wyliczeniowych

Wskazówka

Ta treść jest fragmentem eBooka "Architektura mikrousług .NET dla konteneryzowanych aplikacji .NET", dostępnego na .NET Docs lub jako bezpłatny plik PDF do pobrania i czytania w trybie offline.

Miniatura okładki eBooka „Architektura mikrousług platformy .NET dla konteneryzowanych aplikacji platformy .NET”.

Wyliczenia (lub typy wyliczeniowe w skrócie) to delikatna nakładka językowa na typie całkowitym. Możesz ograniczyć ich użycie do, gdy przechowujesz jedną wartość z zamkniętego zestawu wartości. Klasyfikacja oparta na rozmiarach (małych, średnich, dużych) jest dobrym przykładem. Używanie enumeracji do przepływu sterowania lub bardziej niezawodnych abstrakcji może być nadużyciem kodu. Ten typ użycia prowadzi do kruchego kodu z licznymi instrukcjami sterującymi sprawdzającymi wartości enumeracji.

Zamiast tego można utworzyć klasy Wyliczenia, które umożliwiają korzystanie ze wszystkich zaawansowanych funkcji języka obiektowego.

Jednak nie jest to temat krytyczny, a w wielu przypadkach dla uproszczenia można nadal używać zwykłych typów wyliczenia , jeśli są to twoje preferencje. Użycie typów wyliczeniowych jest bardziej związane z koncepcjami biznesowymi.

Zaimplementuj klasę bazową enumeracji

Mikrousługa zamówień w eShopOnContainers udostępnia przykładową implementację klasy bazowej wyliczenia, jak pokazano w poniższym przykładzie:

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 ...
}

Tej klasy można użyć jako typu w dowolnym obiekcie jednostki lub wartości, tak jak w przypadku następującej CardType klasy : 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)
    {
    }
}

Dodatkowe zasoby