I'm trying to implement a web interface for a user database. Hosts can create guests for their courses, the guests can get deleted after the course has ended but have to remain in the database for a given amount of time. If a host tries to create a guest that already exists in the database, the following things can happen:
- The guest is already active and was created by the same host,
- The guest is already active and was created by a different host,
- The guest is in deleted state and was created by the same host,
- The guest is in deleted state and was created by a different host.
Currently, I'm trying to represent the user state in this enum:
public enum GuestUserStatus
{
Unknown = 0,
NewGuest = 1,
ActiveSameHost = 10,
ActiveDifferentHost = 11,
DeletedSameHost = 20,
DeletedDifferentHost = 21
}
This allows me to switch()
on the set user state.
However, to set the user state, I'm currently using repetetive if clauses like these:
if (queriedUser.GuestDetails.Creator == creator)
{
if (queriedUser.GuestDetails.State == GuestState.Deleted)
{
currentStatus = GuestUserStatus.DeletedSameHost;
}
else
{
currentStatus = GuestUserStatus.ActiveSameHost;
}
}
else
{
if (queriedUser.GuestDetails.State == GuestState.Deleted)
{
currentStatus = GuestUserStatus.DeletedDifferentHost;
}
else
{
currentStatus = GuestUserStatus.ActiveDifferentHost;
}
}
The nested if clauses act on the same condition but with a different outcome.
Is there a way to avoid this? I looked into marking the enum with [Flags]
and using powers of 2 as underlying values, but then I couldn't use the switch()
anymore.
UPDATE: Please note that I have the same conditions twice and different outcomes to them.
UPDATE2: Trying to address the linked question How to tackle a 'branched' arrow head anti-pattern?: Let's say I implement the accepted answer of that question. That would give me something like this:
bool activeSameHost = (queriedUser.Guest.Creator == creator && queriedUser.GuestDetails.State != GuestState.Deleted);
bool activeDifferentHost = (queriedUser.Guest.Creator == creator && queriedUser.GuestDetails.State == GuestState.Deleted);
bool inactiveSameHost = (queriedUser.Guest.Creator != creator && queriedUser.GuestDetails.State == GuestState.Deleted);
bool inativeDifferentHost = (queriedUser.Guest.Creator != creator && queriedUser.GuestDetails.State == GuestState.Deleted);
if(activeSameHost) currentStatus = GuestUserStatus.ActiveSameHost;
if(inactiveSameHost) currentStatus = GuestUserStatus.InactiveSameHost;
if(activeDifferentHost) currentStatus = GuestUserStatus.ActiveDifferentHost;
if(inactiveDifferentHost) currentStatus = GuestUserStatus.InactiveDifferentHost;
I fail to see the improvement. Sure, the if
s are no longer nested, but the only thing that changed is the complexity moving from the nested if
s to the assignment of intermediate variables.
Best Answer
You can use
[Flags]
andswitch
at the same time, simply by defining an alias for the flag combination that interest you.However, in such a design I would try to put the
NotNew
state at 0 instead ofUnknown
, but I do not know your requirements. (What is wrong with modeling it with two booleans instead?)