Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. C#
  4. Something better than Switch Case

Something better than Switch Case

Scheduled Pinned Locked Moved C#
help
16 Posts 7 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    Muammar
    wrote on last edited by
    #1

    Hi, I'm just sick of this lengthy switch case drama and I have a feeling there are already better solutions out there, if not, please help me with a creative way you may have used once to make it easier and shorter.. Many thanks for sharing guys!


    All generalizations are wrong, including this one! (\ /) (O.o) (><)

    A D P C 4 Replies Last reply
    0
    • M Muammar

      Hi, I'm just sick of this lengthy switch case drama and I have a feeling there are already better solutions out there, if not, please help me with a creative way you may have used once to make it easier and shorter.. Many thanks for sharing guys!


      All generalizations are wrong, including this one! (\ /) (O.o) (><)

      A Offline
      A Offline
      akidan
      wrote on last edited by
      #2

      You have a few options... it depends on the situation, really. One possibility is to take the bodies of the case statements and make methods out of them. Another is to create a dictionary of key to delegate, and do a dictionary lookup/invoke in place of a switch. Another is to look for an object-oriented way where you differentiate behavior by overriding an abstract/virtual method, in place of a switch statement somewhere. All depends, though. :)

      M 1 Reply Last reply
      0
      • A akidan

        You have a few options... it depends on the situation, really. One possibility is to take the bodies of the case statements and make methods out of them. Another is to create a dictionary of key to delegate, and do a dictionary lookup/invoke in place of a switch. Another is to look for an object-oriented way where you differentiate behavior by overriding an abstract/virtual method, in place of a switch statement somewhere. All depends, though. :)

        M Offline
        M Offline
        Muammar
        wrote on last edited by
        #3

        Thanks, anyway to do it with Enums you know??


        All generalizations are wrong, including this one! (\ /) (O.o) (><)

        A 1 Reply Last reply
        0
        • M Muammar

          Hi, I'm just sick of this lengthy switch case drama and I have a feeling there are already better solutions out there, if not, please help me with a creative way you may have used once to make it easier and shorter.. Many thanks for sharing guys!


          All generalizations are wrong, including this one! (\ /) (O.o) (><)

          D Offline
          D Offline
          Deresen
          wrote on last edited by
          #4

          Why would you like to throw away the switch case? This is a great way to code statemachines, for instance when you've got a status. Or you use if else, but is like the same as switch case. It really depends on what is it when you would like to get rid of the switch case. It depends on the situation. Show a situation and we'll give the solution.

          1 Reply Last reply
          0
          • M Muammar

            Thanks, anyway to do it with Enums you know??


            All generalizations are wrong, including this one! (\ /) (O.o) (><)

            A Offline
            A Offline
            akidan
            wrote on last edited by
            #5

            Yes, it should work with enums. Again, though, it really depends a lot on what you're trying to do, so it's hard to recommend one approach over another... but here's a sample of some different techniques. Each have their strengths and weaknesses, depending on your situation. Assuming an enum like:

            enum MyEnum { Foo, Bar, Baz }

            switch way:

            bool method(MyEnum val)
            {
            switch (val)
            {
            case MyEnum.Foo:
            Console.WriteLine("Some");
            Console.WriteLine("big");
            Console.WriteLine("case");
            Console.WriteLine("statement");
            Console.WriteLine("that");
            Console.WriteLine("Foo");
            Console.WriteLine("does");
            return true;
            case MyEnum.Bar:
            throw new Exception("Bar!");
            case MyEnum.Baz:
            Console.Beep();
            Console.WriteLine("Beep.");
            return false;
            default:
            throw new ArgumentOutOfRangeException("val");
            }
            }

            Refactor to methods way:

            bool method(MyEnum val)
            {
            switch (val)
            {
            case MyEnum.Foo:
            return FooMethod();
            case MyEnum.Bar:
            return BarMethod();
            case MyEnum.Baz:
            return BazMethod();
            default:
            throw new ArgumentOutOfRangeException("val");
            }
            }

            bool FooMethod()
            {
            Console.WriteLine("Some");
            Console.WriteLine("big");
            Console.WriteLine("case");
            Console.WriteLine("statement");
            Console.WriteLine("that");
            Console.WriteLine("Foo");
            Console.WriteLine("does");
            return true;
            }

            bool BarMethod()
            {
            throw new Exception("Bar!");
            }

            bool BazMethod()
            {
            Console.Beep();
            Console.WriteLine("Beep.");
            return false;
            }

            Dictionary way (.Invoke() is just for clarity):

            delegate bool BoolFunc();
            readonly Dictionary<MyEnum, BoolFunc> methods;

            MyClassConstructor()
            {
            methods = new Dictionary<MyEnum, BoolFunc>();
            methods.Add(MyEnum.Foo, FooMethod);
            methods.Add(MyEnum.Bar, BarMethod);
            methods.Add(MyEnum.Baz, BazMethod);
            }

            bool method(MyEnum val)
            {
            BoolFunc funcToCall;

            if (!methods.TryGetValue(val, out funcToCall))
            	throw new ArgumentOutOfRangeException("val");
            
            return funcToCall.Invoke();
            

            }

            bool FooMethod()
            {
            Console.WriteLine("Some");
            Console.WriteLine("big");
            Console.WriteLine("case");
            Console.WriteLine("statement");
            Console.WriteLine("that");
            Console.WriteLine("Foo");
            Console.WriteLine("does");
            return true;
            }

            bool BarMethod()
            {
            throw new Exception("Bar!");
            }

            bool BazMethod()
            {
            Console.Beep();
            Console.WriteLine("Beep.");
            return false;
            }

            Subclass/override way (the enum actually goes away here):

            b

            P M 2 Replies Last reply
            0
            • M Muammar

              Hi, I'm just sick of this lengthy switch case drama and I have a feeling there are already better solutions out there, if not, please help me with a creative way you may have used once to make it easier and shorter.. Many thanks for sharing guys!


              All generalizations are wrong, including this one! (\ /) (O.o) (><)

              P Offline
              P Offline
              Pete OHanlon
              wrote on last edited by
              #6

              You could always use a Dictionary with an enumeration and a Action to use. For instance, you could have an enumeration that closed a window like this:

              public enum Operation
              {
              Close,
              Save,
              }
              public void Action(Operation action)
              {
              if (_dictionary.ContainsKey(action))
              {
              _dictionary[action]();
              }
              }
              public void Register(Operation operation, Action action)
              {
              _dictionary.Add(operation, action);
              }

              Then, you can add your implementation like this:

              Register(Operation.Close, delegate(){ this.Close(); });

              As you can see, calling this method removes the need for a switch altogether.

              "WPF has many lovers. It's a veritable porn star!" - Josh Smith

              My blog | My articles | MoXAML PowerToys

              L M 2 Replies Last reply
              0
              • A akidan

                Yes, it should work with enums. Again, though, it really depends a lot on what you're trying to do, so it's hard to recommend one approach over another... but here's a sample of some different techniques. Each have their strengths and weaknesses, depending on your situation. Assuming an enum like:

                enum MyEnum { Foo, Bar, Baz }

                switch way:

                bool method(MyEnum val)
                {
                switch (val)
                {
                case MyEnum.Foo:
                Console.WriteLine("Some");
                Console.WriteLine("big");
                Console.WriteLine("case");
                Console.WriteLine("statement");
                Console.WriteLine("that");
                Console.WriteLine("Foo");
                Console.WriteLine("does");
                return true;
                case MyEnum.Bar:
                throw new Exception("Bar!");
                case MyEnum.Baz:
                Console.Beep();
                Console.WriteLine("Beep.");
                return false;
                default:
                throw new ArgumentOutOfRangeException("val");
                }
                }

                Refactor to methods way:

                bool method(MyEnum val)
                {
                switch (val)
                {
                case MyEnum.Foo:
                return FooMethod();
                case MyEnum.Bar:
                return BarMethod();
                case MyEnum.Baz:
                return BazMethod();
                default:
                throw new ArgumentOutOfRangeException("val");
                }
                }

                bool FooMethod()
                {
                Console.WriteLine("Some");
                Console.WriteLine("big");
                Console.WriteLine("case");
                Console.WriteLine("statement");
                Console.WriteLine("that");
                Console.WriteLine("Foo");
                Console.WriteLine("does");
                return true;
                }

                bool BarMethod()
                {
                throw new Exception("Bar!");
                }

                bool BazMethod()
                {
                Console.Beep();
                Console.WriteLine("Beep.");
                return false;
                }

                Dictionary way (.Invoke() is just for clarity):

                delegate bool BoolFunc();
                readonly Dictionary<MyEnum, BoolFunc> methods;

                MyClassConstructor()
                {
                methods = new Dictionary<MyEnum, BoolFunc>();
                methods.Add(MyEnum.Foo, FooMethod);
                methods.Add(MyEnum.Bar, BarMethod);
                methods.Add(MyEnum.Baz, BazMethod);
                }

                bool method(MyEnum val)
                {
                BoolFunc funcToCall;

                if (!methods.TryGetValue(val, out funcToCall))
                	throw new ArgumentOutOfRangeException("val");
                
                return funcToCall.Invoke();
                

                }

                bool FooMethod()
                {
                Console.WriteLine("Some");
                Console.WriteLine("big");
                Console.WriteLine("case");
                Console.WriteLine("statement");
                Console.WriteLine("that");
                Console.WriteLine("Foo");
                Console.WriteLine("does");
                return true;
                }

                bool BarMethod()
                {
                throw new Exception("Bar!");
                }

                bool BazMethod()
                {
                Console.Beep();
                Console.WriteLine("Beep.");
                return false;
                }

                Subclass/override way (the enum actually goes away here):

                b

                P Offline
                P Offline
                Pete OHanlon
                wrote on last edited by
                #7

                There's an even easier way. Take a look at my post below - it's as easy as this.

                "WPF has many lovers. It's a veritable porn star!" - Josh Smith

                My blog | My articles | MoXAML PowerToys

                A 1 Reply Last reply
                0
                • P Pete OHanlon

                  There's an even easier way. Take a look at my post below - it's as easy as this.

                  "WPF has many lovers. It's a veritable porn star!" - Josh Smith

                  My blog | My articles | MoXAML PowerToys

                  A Offline
                  A Offline
                  akidan
                  wrote on last edited by
                  #8

                  Thanks... I did write that way under Dictionary way already, though. :)

                  1 Reply Last reply
                  0
                  • P Pete OHanlon

                    You could always use a Dictionary with an enumeration and a Action to use. For instance, you could have an enumeration that closed a window like this:

                    public enum Operation
                    {
                    Close,
                    Save,
                    }
                    public void Action(Operation action)
                    {
                    if (_dictionary.ContainsKey(action))
                    {
                    _dictionary[action]();
                    }
                    }
                    public void Register(Operation operation, Action action)
                    {
                    _dictionary.Add(operation, action);
                    }

                    Then, you can add your implementation like this:

                    Register(Operation.Close, delegate(){ this.Close(); });

                    As you can see, calling this method removes the need for a switch altogether.

                    "WPF has many lovers. It's a veritable porn star!" - Josh Smith

                    My blog | My articles | MoXAML PowerToys

                    L Offline
                    L Offline
                    led mike
                    wrote on last edited by
                    #9

                    Pete O'Hanlon wrote:

                    As you can see, calling this method removes the need for a switch altogether.

                    Not if you have legacy code as the OP does. He still has to switch the code to the new method. ;P

                    A 1 Reply Last reply
                    0
                    • L led mike

                      Pete O'Hanlon wrote:

                      As you can see, calling this method removes the need for a switch altogether.

                      Not if you have legacy code as the OP does. He still has to switch the code to the new method. ;P

                      A Offline
                      A Offline
                      akidan
                      wrote on last edited by
                      #10

                      Augh... that's terrible. :)

                      1 Reply Last reply
                      0
                      • M Muammar

                        Hi, I'm just sick of this lengthy switch case drama and I have a feeling there are already better solutions out there, if not, please help me with a creative way you may have used once to make it easier and shorter.. Many thanks for sharing guys!


                        All generalizations are wrong, including this one! (\ /) (O.o) (><)

                        C Offline
                        C Offline
                        Christian Graus
                        wrote on last edited by
                        #11

                        The only place where there's a better solution, is where your switches indicate you should have a collection of classes, each representing a different case with the same overloaded method.

                        Christian Graus Driven to the arms of OSX by Vista.

                        1 Reply Last reply
                        0
                        • A akidan

                          Yes, it should work with enums. Again, though, it really depends a lot on what you're trying to do, so it's hard to recommend one approach over another... but here's a sample of some different techniques. Each have their strengths and weaknesses, depending on your situation. Assuming an enum like:

                          enum MyEnum { Foo, Bar, Baz }

                          switch way:

                          bool method(MyEnum val)
                          {
                          switch (val)
                          {
                          case MyEnum.Foo:
                          Console.WriteLine("Some");
                          Console.WriteLine("big");
                          Console.WriteLine("case");
                          Console.WriteLine("statement");
                          Console.WriteLine("that");
                          Console.WriteLine("Foo");
                          Console.WriteLine("does");
                          return true;
                          case MyEnum.Bar:
                          throw new Exception("Bar!");
                          case MyEnum.Baz:
                          Console.Beep();
                          Console.WriteLine("Beep.");
                          return false;
                          default:
                          throw new ArgumentOutOfRangeException("val");
                          }
                          }

                          Refactor to methods way:

                          bool method(MyEnum val)
                          {
                          switch (val)
                          {
                          case MyEnum.Foo:
                          return FooMethod();
                          case MyEnum.Bar:
                          return BarMethod();
                          case MyEnum.Baz:
                          return BazMethod();
                          default:
                          throw new ArgumentOutOfRangeException("val");
                          }
                          }

                          bool FooMethod()
                          {
                          Console.WriteLine("Some");
                          Console.WriteLine("big");
                          Console.WriteLine("case");
                          Console.WriteLine("statement");
                          Console.WriteLine("that");
                          Console.WriteLine("Foo");
                          Console.WriteLine("does");
                          return true;
                          }

                          bool BarMethod()
                          {
                          throw new Exception("Bar!");
                          }

                          bool BazMethod()
                          {
                          Console.Beep();
                          Console.WriteLine("Beep.");
                          return false;
                          }

                          Dictionary way (.Invoke() is just for clarity):

                          delegate bool BoolFunc();
                          readonly Dictionary<MyEnum, BoolFunc> methods;

                          MyClassConstructor()
                          {
                          methods = new Dictionary<MyEnum, BoolFunc>();
                          methods.Add(MyEnum.Foo, FooMethod);
                          methods.Add(MyEnum.Bar, BarMethod);
                          methods.Add(MyEnum.Baz, BazMethod);
                          }

                          bool method(MyEnum val)
                          {
                          BoolFunc funcToCall;

                          if (!methods.TryGetValue(val, out funcToCall))
                          	throw new ArgumentOutOfRangeException("val");
                          
                          return funcToCall.Invoke();
                          

                          }

                          bool FooMethod()
                          {
                          Console.WriteLine("Some");
                          Console.WriteLine("big");
                          Console.WriteLine("case");
                          Console.WriteLine("statement");
                          Console.WriteLine("that");
                          Console.WriteLine("Foo");
                          Console.WriteLine("does");
                          return true;
                          }

                          bool BarMethod()
                          {
                          throw new Exception("Bar!");
                          }

                          bool BazMethod()
                          {
                          Console.Beep();
                          Console.WriteLine("Beep.");
                          return false;
                          }

                          Subclass/override way (the enum actually goes away here):

                          b

                          M Offline
                          M Offline
                          Muammar
                          wrote on last edited by
                          #12

                          Wow, thanks akidan! I think I will go with the last one.


                          All generalizations are wrong, including this one! (\ /) (O.o) (><)

                          A 1 Reply Last reply
                          0
                          • P Pete OHanlon

                            You could always use a Dictionary with an enumeration and a Action to use. For instance, you could have an enumeration that closed a window like this:

                            public enum Operation
                            {
                            Close,
                            Save,
                            }
                            public void Action(Operation action)
                            {
                            if (_dictionary.ContainsKey(action))
                            {
                            _dictionary[action]();
                            }
                            }
                            public void Register(Operation operation, Action action)
                            {
                            _dictionary.Add(operation, action);
                            }

                            Then, you can add your implementation like this:

                            Register(Operation.Close, delegate(){ this.Close(); });

                            As you can see, calling this method removes the need for a switch altogether.

                            "WPF has many lovers. It's a veritable porn star!" - Josh Smith

                            My blog | My articles | MoXAML PowerToys

                            M Offline
                            M Offline
                            Muammar
                            wrote on last edited by
                            #13

                            Hi Pete, I like your solution, it looks short and effecient, however, there's still one big problem.. I cant understand it :-O See, I have this statement:

                                    foreach (DataGridViewColumn grdC in grd.Columns)
                                    {
                                        switch (grdC.HeaderText)
                                        {
                                            case "ID":
                                                grdC.HeaderText = "id";
                                                break;
                                            case "NAME":
                                                grdC.HeaderText = "name";
                                                break;
                                            ...
                                        }
                                    }
                            

                            All generalizations are wrong, including this one!
                            (\ /)
                            (O.o)
                            (><)

                            J 1 Reply Last reply
                            0
                            • M Muammar

                              Hi Pete, I like your solution, it looks short and effecient, however, there's still one big problem.. I cant understand it :-O See, I have this statement:

                                      foreach (DataGridViewColumn grdC in grd.Columns)
                                      {
                                          switch (grdC.HeaderText)
                                          {
                                              case "ID":
                                                  grdC.HeaderText = "id";
                                                  break;
                                              case "NAME":
                                                  grdC.HeaderText = "name";
                                                  break;
                                              ...
                                          }
                                      }
                              

                              All generalizations are wrong, including this one!
                              (\ /)
                              (O.o)
                              (><)

                              J Offline
                              J Offline
                              J4amieC
                              wrote on last edited by
                              #14

                              your code is a WTF! All you're doing is lower-casing the header. This would suffice

                              foreach (DataGridViewColumn grdC in grd.Columns)
                              {
                              grdC.HeaderText = grdC.HeaderText.ToLower();
                              }

                              M 1 Reply Last reply
                              0
                              • J J4amieC

                                your code is a WTF! All you're doing is lower-casing the header. This would suffice

                                foreach (DataGridViewColumn grdC in grd.Columns)
                                {
                                grdC.HeaderText = grdC.HeaderText.ToLower();
                                }

                                M Offline
                                M Offline
                                Muammar
                                wrote on last edited by
                                #15

                                J4amieC wrote:

                                your code is a WTF! All you're doing is lower-casing the header.

                                :laugh: :laugh: I'm sorry, I guess it was a bad example :-D, OF COURSE this's not what I'm doing, I'm just giving an example, obviously a bad one:) ok, let's give it a try again and try setting the text to whatever.. I'm sorry for the confusion mate:)


                                All generalizations are wrong, including this one! (\ /) (O.o) (><)

                                1 Reply Last reply
                                0
                                • M Muammar

                                  Wow, thanks akidan! I think I will go with the last one.


                                  All generalizations are wrong, including this one! (\ /) (O.o) (><)

                                  A Offline
                                  A Offline
                                  akidan
                                  wrote on last edited by
                                  #16

                                  My pleasure! :) Happy I could help.

                                  1 Reply Last reply
                                  0
                                  Reply
                                  • Reply as topic
                                  Log in to reply
                                  • Oldest to Newest
                                  • Newest to Oldest
                                  • Most Votes


                                  • Login

                                  • Don't have an account? Register

                                  • Login or register to search.
                                  • First post
                                    Last post
                                  0
                                  • Categories
                                  • Recent
                                  • Tags
                                  • Popular
                                  • World
                                  • Users
                                  • Groups