Verwenden von Enumerationsklassen anstelle von Enumerationstypen
Tipp
Diese Inhalte sind ein Auszug aus dem eBook „.NET Microservices Architecture for Containerized .NET Applications“, verfügbar unter .NET Docs oder als kostenlos herunterladbare PDF-Datei, die offline gelesen werden kann.
Bei Enumerationen (bzw. Enumerationstypen) handelt es sich um dünne Sprachwrapper um einen integralen Typ. Sie sollten deren Verwendung darauf beschränken, einen Wert aus einem vollständigen Wertesatz zu speichern. Klassifizierung anhand von 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 instabilem Code mit vielen Anweisungen für die Ablaufsteuerung, die die Werte der Enumeration überprüfen.
Sie können stattdessen Enumerationsklassen erstellen, um die umfassenden Features von objektorientierten Sprachen nutzen zu können.
Dabei handelt es sich jedoch nicht um ein kritisches Thema und in vielen Fällen können Sie aus Gründen der Einfachheit dennoch reguläre Enumerationstypen verwenden, wenn Sie diese bevorzugen. Die Verwendung von Enumerationsklassen steht eher im Bezug zu geschäftlichen Konzepten.
Implementieren einer Basisklasse für Enumerationen
Der Microservice für Bestellungen in eShopOnContainers stellt wie im Folgenden dargestellt ein Beispiel für die Implementierung einer Basisklasse für Enumerationen bereit:
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, z.B. für die folgende CardType
:Enumeration
-Klasse:
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)
{
}
}
Zusätzliche Ressourcen
Jimmy Bogard. Enumeration classes (Enumerationsklassen)
https://lostechies.com/jimmybogard/2008/08/12/enumeration-classes/Steve Smith. Enum Alternatives in C# (Alternativen zu Enumerationen in C#)
https://ardalis.com/enum-alternatives-in-cEnumeration.cs. Base Enumeration class in eShopOnContainers (Die Basisklasse „Enumeration“ in eShopOnContainers)
https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/SeedWork/Enumeration.csCardType.cs. Beispielklasse für Enumerationen in eShopOnContainers.
https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/CardType.csSmartEnum. Ardalis: Klassen zum Erzeugen von stark typisierten intelligenteren Enumerationen in .NET
https://www.nuget.org/packages/Ardalis.SmartEnum/