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

    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