Usare le classi di enumerazione anziché i tipi enum
Suggerimento
Questo contenuto è un estratto dell'eBook "Microservizi .NET: Architettura per le applicazioni .NET incluse in contenitori", disponibile in .NET Docs o come PDF scaricabile gratuitamente e da poter leggere offline.
Le enumerazioni (o tipi enum) sono un sottile wrapper del linguaggio per un tipo integrale. È possibile limitarne l'uso quando si archivia un valore da un set di valori chiuso. La classificazione in base alle dimensioni (piccole, medie e grandi) rappresenta un buon esempio. L'uso delle enumerazioni per il flusso di controllo o per astrazioni più potenti può indicare difetti di programmazione noti come code smell. Questo tipo di utilizzo determina un codice fragile con molte istruzioni del flusso di controllo che verificano i valori dell'enumerazione.
In alternativa, è possibile creare classi di enumerazione che abilitano tutte le funzionalità avanzate di un linguaggio orientato a oggetti.
Tuttavia, questo non è un argomento strategico e in molti casi, per semplicità è comunque possibile continuare a usare i normali tipi enum se si preferisce. L'uso delle classi di enumerazione è più correlato ai concetti relativi all'azienda.
Implementare una classe di base di enumerazione
Il microservizio degli ordini nell'app eShopOnContainers fornisce un'implementazione della classe di base di enumerazione di esempio, come mostrato di seguito:
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 ...
}
È possibile usare questa classe come un tipo in qualsiasi entità o oggetto valore, come per la classe CardType
: Enumeration
seguente:
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)
{
}
}
Risorse aggiuntive
Jimmy Bogard. Enumeration classes (Classi di enumerazione)
https://lostechies.com/jimmybogard/2008/08/12/enumeration-classes/Steve Smith. Enum Alternatives in C# (Alternative agli enum in C#)
https://ardalis.com/enum-alternatives-in-cEnumeration.cs. Base Enumeration class in eShopOnContainers (Classe di enumerazione di base in eShopOnContainers)
https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/SeedWork/Enumeration.csCardType.cs. Classe di enumerazione di esempio in eShopOnContainers.
https://github.com/dotnet-architecture/eShopOnContainers/blob/dev/src/Services/Ordering/Ordering.Domain/AggregatesModel/BuyerAggregate/CardType.csSmartEnum. Ardalis - Classi che consentono di produrre enum fortemente tipizzati e più intelligenti in .NET.
https://www.nuget.org/packages/Ardalis.SmartEnum/