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 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