Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
---
title: Using Enumeration classes instead of enum types
description: .NET Microservices Architecture for Containerized .NET Applications | Lear how you can use enumeration classes, instead of enums, as a way to solve some limitations of the latter.
ms.date: 10/08/2018
ms.date: 11/25/2020
---
# Use enumeration classes instead of enum types

[Enumerations](../../../csharp/language-reference/builtin-types/enum.md) (or *enum types* for short) are a thin language wrapper around an integral type. You might want to limit their use to when you are storing one value from a closed set of values. Classification based on sizes (small, medium, large) is a good example. Using enums for control flow or more robust abstractions can be a [code smell](https://deviq.com/code-smells/). This type of usage leads to fragile code with many control flow statements checking values of the enum.

Instead, you can create Enumeration classes that enable all the rich features of an object-oriented language.

However, this isn't a critical topic and in many cases, for simplicity, you can still use regular [enum types](../../../csharp/language-reference/builtin-types/enum.md) if that's your preference. Anyway, the use of enumeration classes is more related to business-related concepts.
However, this isn't a critical topic and in many cases, for simplicity, you can still use regular [enum types](../../../csharp/language-reference/builtin-types/enum.md) if that's your preference. The use of enumeration classes is more related to business-related concepts.

## Implement an Enumeration base class

Expand All @@ -22,29 +22,23 @@ public abstract class Enumeration : IComparable

public int Id { get; private set; }

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

public override string ToString() => Name;

public static IEnumerable<T> GetAll<T>() where T : Enumeration
{
var fields = typeof(T).GetFields(BindingFlags.Public |
BindingFlags.Static |
BindingFlags.DeclaredOnly);

return fields.Select(f => f.GetValue(null)).Cast<T>();
}
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)
{
var otherValue = obj as Enumeration;

if (otherValue == null)
if (obj is not Enumeration otherValue)
{
return false;
}

var typeMatches = GetType().Equals(obj.GetType());
var valueMatches = Id.Equals(otherValue.Id);
Expand All @@ -61,11 +55,12 @@ public abstract class Enumeration : IComparable
You can use this class as a type in any entity or value object, as for the following `CardType` : `Enumeration` class:

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

public CardType(int id, string name)
: base(id, name)
Expand Down