Thursday, September 1, 2011

An other view on a Switch Case

As first post I'm was inspired by this post. I thought about what Anoop said and started thinking about possible variations.

But lets start with the basics, right. If you stranded on this page I assume you know a wee bit about programming or a lot more then I do. (Just to note that I'm always open for tips, hints, criticism, ...)


A basic switch case in c# looks like this:
   1: var str = "Toad";
   2:             switch (str)
   3:             {
   4:                 case "Bird" :
   5:                     Console.WriteLine("It's a bird!");
   6:                     break;
   7:                 case "Toad" :
   8:                     Console.WriteLine("It's a toad!");
   9:                     break;
  10:                 default:
  11:                     Console.WriteLine(string.Format("I don't know a {0}.",str));
  12:                     break;
  13:             }




Nothing really special about it, when you have read through Anoop’s post you can alter a switch case to be the following:



   1: public class SwitchCase : Dictionary<string, Action>
   2:    {
   3:        public Action DefaultAction
   4:        {
   5:            get;
   6:            set;
   7:        }
   8:  
   9:        public SwitchCase(Action defaultAction)
  10:        {
  11:            DefaultAction = defaultAction;
  12:        }
  13:  
  14:        public void Eval(string param)
  15:        {
  16:            if (ContainsKey(param))
  17:            {
  18:                this[param]();
  19:            }
  20:            else
  21:            {
  22:                if (DefaultAction == null)
  23:                    throw new NullReferenceException("Default action may not be null.");
  24:                DefaultAction();
  25:            }
  26:        }
  27:    }



Usage:




   1: var sc = new SwitchCase(() => Console.WriteLine("The default action"))
   2:                          {
   3:                              {"Case1", () => Console.WriteLine("Case 1")},
   4:                              {"Case2", () => Console.WriteLine("Case 2")},
   5:                              {"Case3", () => Console.Write("Case 3")}
   6:                          };
   7:  
   8:             sc.Eval("Case1");

Or converting this into a generic becomes:


   1: public class ActionSwitchCase<TTkey> : Dictionary<TTkey, Action>
   2:     {
   3:         public Action DefaultAction
   4:         {
   5:             get;
   6:             set;
   7:         }
   8:  
   9:         public ActionSwitchCase(Action defaultAction)
  10:         {
  11:             DefaultAction = defaultAction;
  12:         }
  13:  
  14:         public void Eval(TTkey key)
  15:         {
  16:             if (ContainsKey(key))
  17:             {
  18:                 this[key]();
  19:             }
  20:             else
  21:             {
  22:                 if (DefaultAction == null)
  23:                     throw new NullReferenceException("Default action may not be null.");
  24:                 DefaultAction();
  25:             }
  26:         }
  27:     }



Which you could use as:



   1: var asc = new ActionSwitchCase<string>(() => Console.WriteLine("Default!"))
   2:                                         {
   3:                                             {"Case1",() => Console.WriteLine("Case 1")},
   4:                                             {"Case2",() => Console.WriteLine("Case 2")},
   5:                                             {"Case3",() => Console.WriteLine("Case 3")}
   6:                                         };
   7:  
   8:             asc.Eval("Case1");



While actually putting it a bit further is applying it to functions, creating the following class:


   1: public class FuncSwitchCase<TTKey, TInpuType, TResultType> :
   2:         Dictionary<TTKey, Func<TInpuType, TResultType>>
   3:     {
   4:         public Func<TInpuType, TResultType> DefaultFunction
   5:         {
   6:             get;
   7:             set;
   8:         }
   9:  
  10:         public FuncSwitchCase(Func<TInpuType, TResultType> defaultFunc)
  11:         {
  12:             DefaultFunction = defaultFunc;
  13:         }
  14:  
  15:         public TResultType Eval(TTKey key, TInpuType param)
  16:         {
  17:             TResultType output;
  18:  
  19:             if (ContainsKey(key))
  20:                 output = this[key].Invoke(param);
  21:             else
  22:             {
  23:                 if (DefaultFunction == null)
  24:                     throw new NullReferenceException("Default function may not be null.");
  25:                 output = DefaultFunction(param);
  26:             }
  27:  
  28:             return output;
  29:         }
  30:     }



Which then could be used as:


   1: Func<string,string> f1 = (x) => x + "function 1";
   2:             Func<string, string> f2 = (x) => x + "function 2";
   3:             Func<string, string> df = (x) => x + "default";
   4:  
   5:             var fsc = new FuncSwitchCase<string, string, string>(df)
   6:                           {
   7:                               {"Case1", f1},
   8:                               {"Case2", f2}
   9:                           };
  10:  
  11:             Console.WriteLine(fsc.Eval("Case1","To hell with..."));

This opens a few doors in create switch cases. And credits to Anoop’s post putting down the idea.

Regards,
Kyor



 

No comments:

Post a Comment