3

I'm working with a switch statement that sets certain properties of an object dependent on a case - a new requirement has came in to add a case statement 'All' to essentially execute all the cases to apply all the fields - used in exceptional cases.

I can't really find a nice solution around this, each case statement is only setting 1-2 property values so it wouldn't be worth separating the logic into methods. However, I also don't want to have a load of duplicate code.

var person = new Person(); switch (PersonEnum) { case PersonEnum.Name: person.Name = ... break; case PersonEnum.Age: person.Age = ... break; case PersonEnum.All: person.Name = ... person.Age = ... break; 

The example code above is a far more simplified version of what I'm dealing with, but the idea still applies.

1
  • How much "simplified" is the code? Because this looks like the exact purpose for which the Factory pattern was invented Commented Jan 31, 2019 at 23:43

3 Answers 3

6

It will be more practical to use Flags enum. In this case you can do something like this:

if (PersonEnum.HasFlag(PersonEnum.Name)) // Name is set. HasFlag is equivalent to (PersonEnum & PersonEnum.Name) != 0 { person.Name = ... } if (PersonEnum.HasFlag(PersonEnum.Age)) // Age is set { person.Age = ... } ... 

In this case you don't even need to check PersonEnum.All

Your enum should be something like this:

[Flags] enum PersonEnum { Name = 1, Age = 2, LastName = 4, ... NameAndAge = Name | Age, All = Name | Age | LastName ... } 
Sign up to request clarification or add additional context in comments.

6 Comments

You likely would be happier with Enum.HasFlag: learn.microsoft.com/en-us/dotnet/api/…
@Flydog57, true that! Seems I'm a bit old-schoolish :)
This answer is missing the actual answer: "no, it is not possible". It's not "more practical" if there is no other way
The advantage of Enum.HasFlag is that you don't have to think hard about getting the masking right (and, or, == or whatever).
Actually, you don't want the else if, you just want if. That way if both Name and Age are set, you will run though both blocks of code. If you want to work with else if coding, you can actually do it with a switch statement with pattern matching cases couple with when clauses.
|
1

You could separate it into if statements instead to minimize the code a bit

if (PersonEnum == PersonEnum.All || PersonEnum == PersonEnum.Name) person.Name = ... if (PersonEnum == PersonEnum.All || PersonEnum == PersonEnum.Age) person.Age = ... 

Comments

0

Actually there is a way to do this, it is not as nice as the fall through that Java supports but you can achieve something similar with goto, yep there it is. One should point out that although there is stigma associated with the goto statement perhaps this is the one place where it would be ok, preferably if the code is short, concise and easy to read.

However for this particular scenario it might not be the best choice. A better choice here would be the factory pattern.

switch (personEnum) { case PersonEnum.Name: person.Name = ""; goto case PersonEnum.Age; case PersonEnum.Age: ... 

2 Comments

I don't think this is correct. With your code, any personEnum with PersonEnum.Name set will run the case PersonEnum.Age case's code, whether or not PersonEnum.Age is set or not.
@Flydog57 - No it is not the proper implementation. I put it in to highlight that you can do a poor man's fall through but I highlighted that in this situation something like the factory pattern would be a better choice. I wasn't trying to solve the code for the OP just show that it could be done.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.