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