Probably every programmer knows switch-case keywords. They are often used to convert data, e.g. some string from another (sub)system to your enum. While working with those, I found two patterns I call best practices.

The first one uses return outright. Its code is short and elegant:

transformGender(String gender) {
    switch(gender) {
        case "M": return Gender.MALE;
        case "F": return Gender.FEMALE;
        case "I": return Gender.INTERSEX;
        default:  return Gender.UNKNOWN;
    }
}

However, some might argue it doesn’t follow the single-exit pattern. If you happen to add e.g. logging, it makes it complicated. Since copy-pasting code would make it a direct opposite of what you were trying to do there, a different pattern should be used. I found one:

transformGender(String gender) {
    final Gender result;
    switch(gender) {
        case "M": result = Gender.MALE;
                  break;
        case "F": result = Gender.FEMALE;
                  break;
        case "I": result = Gender.INTERSEX;
                  break;
        default:  result = Gender.UNKNOWN;
    }
    return result;
}

Obviously, the price for single exit is a longer code (breaks, storing the value). However, it still keeps one advantage of the previous pattern (the basic Java tutorial doesn’t teach it): You can be sure your result is not modified, thanks to final keyword. If you fail to write the value exactly once, a compiler error warns you instantly. Also, it makes it hard to write messy code with preset value and no default branch.

I was curious if the pattern can be used in C#, but it seems it can’t. The keyword final has no equivalent in C#, with readonly not really working in the same manner. Where readonly states that it can only be written in constructor or declaration, final means that the field or variable can only be written once.

Comments

2 COMMENTS

  1. Indeed an immediate return looks a bit nicer to my eyes than the repeated break statements so I use it often. If you need logging after the switch you could also use a little helper method that invokes the original method and then does the logging. (You could also use try/finally around the switch but I’d argue this is unconventional so I’d prefer the break statements over it. It also runs the finally code even when an exception occurs which may not be what you want. If the finally code throws an exception it can even hide the original exception…)

    • Yeah, a method or try/finally would do as well. So you either have to add a method, add a try/finally block or make it longer with the breaks. Each approach has is advantages and disadvantages and I think it is up to the team or company to set up code conventions.

Comments are closed.