C# – Enums and Bug Resilience

Our domain is made of sets. Some sets are trivial such as all integers (int) or all booleans (bool) but often we are dealing with sets that are more narrow, for example the possible states of an order (Incomplete, Unpaid, Paid, Shipped, etc.).

In our …


This content originally appeared on DEV Community and was authored by Aviad Pineles

Our domain is made of sets. Some sets are trivial such as all integers (int) or all booleans (bool) but often we are dealing with sets that are more narrow, for example the possible states of an order (Incomplete, Unpaid, Paid, Shipped, etc.).

In our database we assign a number or a string that represents each possible value, and in our code we use an Enum for that. This is good, but if we are not careful, then at some point in the future, when we change the composition of the set (for example by adding another state Received), we might create hard to debug errors in our program.

We want to always use switch when dealing with these sets, so that when the set changes, the compiler automatically warns us about all the places where code might need to be changed.

However there's one case where this is tricky: when dealing with the database. For example, we have a query in our code that fetches all orders that are paid, so our LINQ condition could be something like this:

where order.status == OrderStatus.Paid ||
      order.status == OrderStatus.Shipped

But what happens when we now add the new Received state? This query is now broken because received orders are also paid, but the compiler doesn't have any way of knowing that!

We need to somehow add a switch to this operation to make it safe. What we must do is filter all the elements of the enum by our condition:

IEnumerable<OrderStatus> GetOrderStatusValuesWhichArePaid() {
    static bool IsPaid(OrderStatus orderStatus) => orderStatus switch {
        OrderkStatus.Incomplete => false,
        OrderkStatus.Unpaid => false,
        OrderkStatus.Paid => true,
        OrderkStatus.Shipped => true,
        _ => throw new ArgumentOutOfRangeException(nameof(orderStatus))
    };

    return Enum.GetValues<OrderStatus>().Where(IsPaid);
}

And we can use it in our LINQ query:

var paidStatusValues = GetOrderStatusValuesWhichArePaid();
var query = from order in Orders
            where paidStatusValues.Contains(order.status)
            select order;

Now when we add the new Received state, the compiler can warn us that the switch statement in the function IsPaid is not covering all cases properly.


This content originally appeared on DEV Community and was authored by Aviad Pineles


Print Share Comment Cite Upload Translate Updates
APA

Aviad Pineles | Sciencx (2021-09-27T13:20:30+00:00) C# – Enums and Bug Resilience. Retrieved from https://www.scien.cx/2021/09/27/c-enums-and-bug-resilience/

MLA
" » C# – Enums and Bug Resilience." Aviad Pineles | Sciencx - Monday September 27, 2021, https://www.scien.cx/2021/09/27/c-enums-and-bug-resilience/
HARVARD
Aviad Pineles | Sciencx Monday September 27, 2021 » C# – Enums and Bug Resilience., viewed ,<https://www.scien.cx/2021/09/27/c-enums-and-bug-resilience/>
VANCOUVER
Aviad Pineles | Sciencx - » C# – Enums and Bug Resilience. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2021/09/27/c-enums-and-bug-resilience/
CHICAGO
" » C# – Enums and Bug Resilience." Aviad Pineles | Sciencx - Accessed . https://www.scien.cx/2021/09/27/c-enums-and-bug-resilience/
IEEE
" » C# – Enums and Bug Resilience." Aviad Pineles | Sciencx [Online]. Available: https://www.scien.cx/2021/09/27/c-enums-and-bug-resilience/. [Accessed: ]
rf:citation
» C# – Enums and Bug Resilience | Aviad Pineles | Sciencx | https://www.scien.cx/2021/09/27/c-enums-and-bug-resilience/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.