Click here to Skip to main content
15,885,546 members
Articles / Programming Languages / C#

Beware of switch

Rate me:
Please Sign up or sign in to vote.
4.60/5 (9 votes)
20 Aug 2012CPOL1 min read 20.4K   7   22
Beware of switch

I am by no means against any of the instructions which exist in C#, including goto (wow, I said that). Each of them can have its place and its normal use in an application. However, things can be abused and code gets nasty.

For example, let’s consider we are displaying a hierarchy of people in an organization in a tree-like visual component. We will create a class that models a person:

C#
public class Person
{
    public string Name { get; set; }
    public IEnumerable Subordinates { get; set; }
}

All is nice but some requests come in, such as : each type of person should have a distinctive icon at its left, the managers should have salutation type displayed, etc.

Then you think “I know, I’ll create a PersonType enum”. That’s when things will begin to get nasty.

C#
public enum PersonType
{
    Undefined,
    Simple,
    Manager
}

public class Person
{
    public IEnumerable Subordinates { get; set; }

    // new members :
    public PersonType Type { get; set; }
    public string Salutation { get; set; }
    private string _name;

    // modified members :
    public string Name
    {
        get
        {
             switch(Type)
             {
                 case PersonType.Simple: return _name;
                 case PersonType.Manager : return Salutation + " " + _name;
                 default : throw new InvalidOperationException();
             }
        }
        set { _name = value; }
    }

    public Image Icon
    {
        get
        {
            switch(Type)
            {
                 case PersonType.Simple: return Icons.SimplePersonIcon;
                 case PersonType.Manager : return Icons.ManagerIcon;
                 default : throw new InvalidOperationException();
            }
        }
    }
}

If you find yourself writing switches in one or more properties or methods of the class, switching on the same thing (PersonType here), then stop it. You are writing hard-to-maintain and error-prone code. Plus, it's inelegant. This practically is a cry for polymorphism.

The right thing to do™ is to have three classes: an abstract Person class, a SimplePerson class (inheriting the Person class) and a ManagerPerson class (also inheriting the Person class):

C#
public abstract class Person
{
    public virtual string Name { get; set; }
    public IEnumerable Subordinates { get; set; }
    public abstract Image Icon { get; }
    public string Salutation { get; set; }
}

public class SimplePerson : Person
{
    public override Image Icon { get { Icons.SimplePersonIcon; } }
}

public class ManagerPerson : Person
{
    private string _name;

    public override Image Icon { get { Icons.ManagerIcon; } }
    public override string Name
    {
        get
        {
            return Salutation + " " + _name;
        }
        set
        {
            _name = value;
        }
    }
}

Notice that the code is shorter, simpler to follow and understand. Furthermore, although we did introduce two more classes, we also removed the PersonType enum so at a total, we introduced only one more class.

This article was originally posted at http://blog.andrei.rinea.ro?p=181

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) IBM, Business Analytics
Romania Romania
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralMy vote of 5 Pin
Christian Amado21-Aug-12 5:42
professionalChristian Amado21-Aug-12 5:42 
QuestionBug! Pin
andychurchill20-Aug-12 5:51
andychurchill20-Aug-12 5:51 
AnswerRe: Bug! Pin
Andrei Ion Rînea20-Aug-12 5:56
Andrei Ion Rînea20-Aug-12 5:56 
GeneralRe: Bug! Pin
Andrei Ion Rînea20-Aug-12 5:57
Andrei Ion Rînea20-Aug-12 5:57 
QuestionPolymorphism Pin
David Pierson19-Aug-12 20:40
David Pierson19-Aug-12 20:40 
GeneralRe: Polymorphism Pin
Martijn Kok21-Aug-12 1:22
Martijn Kok21-Aug-12 1:22 
GeneralRe: Polymorphism Pin
David Pierson21-Aug-12 13:32
David Pierson21-Aug-12 13:32 
Appreciate your reply and thoughts on this. Interfaces do go some of the way towards polymorphism, but do not really satisfy the requirement. For the single reason that the code to implement the interfaces must be reproduced in each and evey implementation. Duplication of code has always proven a bugbear and timewaster of maintenance time. Sure it is quick to code and may be suitable for systems that do not have a great life expectancy or likelihood of needing to be maintained. But for enterprise systems (my world), it really does not cut it. I do understand the real-world difficulties of implementing it, so my complaint is kind of hypothetical.

Having said that C# is still a galaxy ahead of anything else for this type of work Smile | :)
GeneralRe: Polymorphism Pin
Martijn Kok21-Aug-12 20:06
Martijn Kok21-Aug-12 20:06 
GeneralRe: Polymorphism Pin
Richard Deeming23-Aug-12 9:24
mveRichard Deeming23-Aug-12 9:24 
GeneralRe: Polymorphism Pin
Martijn Kok23-Aug-12 10:06
Martijn Kok23-Aug-12 10:06 
GeneralMy vote of 5 Pin
cpkilekofp17-Aug-12 7:42
cpkilekofp17-Aug-12 7:42 
GeneralThoughts Pin
PIEBALDconsult15-Aug-12 14:35
mvePIEBALDconsult15-Aug-12 14:35 
GeneralRe: Thoughts Pin
Andrei Ion Rînea15-Aug-12 23:20
Andrei Ion Rînea15-Aug-12 23:20 
GeneralRe: Thoughts Pin
PIEBALDconsult16-Aug-12 3:26
mvePIEBALDconsult16-Aug-12 3:26 
GeneralRe: Thoughts Pin
cpkilekofp17-Aug-12 7:45
cpkilekofp17-Aug-12 7:45 
GeneralRe: Thoughts Pin
PIEBALDconsult17-Aug-12 7:59
mvePIEBALDconsult17-Aug-12 7:59 
GeneralRe: Thoughts Pin
Andrei Ion Rînea17-Aug-12 11:09
Andrei Ion Rînea17-Aug-12 11:09 
GeneralRe: Thoughts Pin
Tiefeng You21-Aug-12 11:39
Tiefeng You21-Aug-12 11:39 
GeneralRe: Thoughts Pin
PIEBALDconsult21-Aug-12 15:21
mvePIEBALDconsult21-Aug-12 15:21 
GeneralRe: Thoughts Pin
Andrei Ion Rînea22-Aug-12 2:22
Andrei Ion Rînea22-Aug-12 2:22 
SuggestionGood source Pin
Clifford Nelson15-Aug-12 14:05
Clifford Nelson15-Aug-12 14:05 
GeneralRe: Good source Pin
Ramesh Muthiah17-Aug-12 20:12
Ramesh Muthiah17-Aug-12 20:12 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.