Click here to Skip to main content
Click here to Skip to main content

Tagged as

Go to top

Refactoring "switch cases".

, 2 Jul 2009
Rate this:
Please Sign up or sign in to vote.
Hello to everyone, I want to show you how to apply a simple refactoring trick to a common pattern, the "switch case" statement. Please take a look at the following program (a console app) : class Program     {         private static stri

Hello to everyone, I want to show you how to apply a simple refactoring trick to a common pattern, the "switch case" statement.

Please take a look at the following program (a console app) :

class Program
    {
        private static string options = null;
        private static readonly Type sportsEnumType = typeof(SportNews.Sports);
        static void Main(string[] args)
        {
            SportNews news = new SportNews();
            while (true)
            {
                Console.WriteLine();
                DisplayOptions();
                string key = Console.ReadKey().KeyChar.ToString();
                Console.WriteLine();
                try
                {
                    SportNews.Sports sport = (SportNews.Sports)(Enum.Parse(
                        sportsEnumType, key));
                    news.DisplayNews(sport);
                }
                catch(Exception ex)
                {
                    Console.WriteLine(ex);
                    Console.ReadLine();
                    return;
                }
 
            }
        }
        private static void DisplayOptions()
        {

            if (options == null)
            {
                StringBuilder optionsBuilder = new StringBuilder();
                FieldInfo[] enumFields = sportsEnumType.UnderlyingSystemType.GetFields(
                    BindingFlags.Public | BindingFlags.Static);
                foreach (FieldInfo enumField in enumFields)
                {
                    object enumValue = enumField.GetRawConstantValue();
                    SportNews.Sports sport = (SportNews.Sports)(enumValue);
                    optionsBuilder.AppendFormat("To display the news for {0} press {1}\n",
                        sport, enumValue);
                }
                options = optionsBuilder.ToString();
            }
            Console.WriteLine(options);
        }
    }

    public class SportNews
    {
        public enum Sports
        {
            Soccer = 0,
            BasketBall = 1,
            Rugby = 2,
            VolleyBall = 3
        }
        public void DisplayNews(Sports sport)
        {
            switch (sport)
            {
                case Sports.Soccer:
                    DisplayNewsForSoccer();
                    break;
                case Sports.BasketBall:
                    DisplayNewsForBasketBall();
                    break;
                case Sports.Rugby:
                    DisplayNewsForRugby();
                    break;
                case Sports.VolleyBall:
                    DisplayNewsForVolleyBall();
                    break;
                default:
                    throw new NotImplementedException(string.Format(
                         "The method for the sport {0} is not implemented", sport));
            }
        }
 
        private void DisplayNewsForSoccer()
        {
            Console.WriteLine("Displaying News for Soccer");
            // Real implementation below
            // Do something
        }
        private void DisplayNewsForBasketBall()
        {
            Console.WriteLine("Displaying News for BasketBall");
            // Real implementation below
            // Do something
        }
 
        private void DisplayNewsForRugby()
        {
            Console.WriteLine("Displaying News for Rugby");
            // Real implementation below
            // Do something
        }
 
        private void DisplayNewsForVolleyBall()
        {
            Console.WriteLine("Displaying News for VolleyBall");
            // Real implementation below
            // Do something
        }
     }

What this does?, well, simply ask to the user to press a given key to execute a determined action.

The running program looks like this:

console_app_running

Very simple isn't?

This is fine for the number of alternatives that we are going to handle, but,what about if you add more items (+10) to the enum, you would need to add more cases to the switch statement, and so on. This is a very error prone process and also a maintenance nightmare.

What to do then? Well, the solution is very simple, you would need to change the switch statement by a lookup table, a Dictionary object is a good candidate to do this.

SHOW ME THE CODE!!. Here it is:

First lets create our Dictionary instance in the SportNews class constructor :

      private Dictionary<Sports, Action> lookupTable;
        public SportNews()
        {
            lookupTable = new Dictionary<Sports, Action>()
            {
                { Sports.Soccer, DisplayNewsForSoccer },
                { Sports.BasketBall, DisplayNewsForBasketBall },
                { Sports.Rugby, DisplayNewsForRugby },
                { Sports.VolleyBall, DisplayNewsForVolleyBall }
            };
        }

Now lets change the DiplayNews method to get ride of the switch statement, it will end up as:

        public void DisplayNews(Sports sport)
        {
            Action displayMethod;
            if (lookupTable.TryGetValue(sport, out displayMethod))
            {
                displayMethod.Invoke();
            }
            else
            {
                throw new NotImplementedException(string.Format(
                   "The method for the sport {0} is not implemented", sport));
            }
        }

Isn't this more simple and clean?

Obviously, this code could be refactored even more, but for the purpose of the article I think is fine.

The final working demo can be found here.

Bye bye.

Shameless plug: You can check this article on my blog here.

License

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

Share

About the Author

emiaj
Web Developer
Peru Peru
No Biography provided

Comments and Discussions

 
GeneralMy vote of 2 PinmemberBigTuna9-Apr-09 4:30 
GeneralRe: My vote of 2 Pinmemberemiaj13-Apr-09 4:40 
GeneralRe: My vote of 2 Pinmemberemiaj24-Jun-09 5:26 
Generalswitch() Pinmembertonyt8-Apr-09 20:56 
GeneralMy vote of 1 PinmembernextDev.net7-Apr-09 20:52 
GeneralRe: My vote of 1 PinmemberDoncp8-Apr-09 10:46 

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

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

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 2 Jul 2009
Article Copyright 2009 by emiaj
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid