Something better than Switch Case
-
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) (><)
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
-
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
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
-
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
-
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
-
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
-
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) (><)
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.
-
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
-
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
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)
(><) -
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)
(><) -
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();
}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) (><)
-
Wow, thanks akidan! I think I will go with the last one.
All generalizations are wrong, including this one! (\ /) (O.o) (><)