I want to write readable code like below to handle different sub types. Let’s say if I want to take a shower for my pets. Depending on the pet type, I will like to handle it differently. As you can tell, if statements can do the work but it will be very messy. I would like to use switch statement. However, C# compiler doesn’t want to get into this business. That’s alright. I will like to do it myself. Here is a clean solution. The ultmiate code is very easy to read. No if statements. Zero. None. Nil. There are 3 simple steps.
myPet.Switch()
.Case<Dog>(x => HandleDog(x))
.Case<Cat>(x => HandleCat(x))
.Case<Parrot>(x => HandleParrot(x))
.Default<Pet>(x => HandleDefault(x));
Step 1: Create a Switch class.
public class Switch
{
public Switch(object o)
{
Target = o;
}
public object Target { get; set; }
}
Step 2: Create extension methods to support fluent API, supporting, predict, fall through, and default.
public static class SwitchExtensions
{
public static Switch Case<T>(this Switch switcher,
Action<T> action) where T : class
{
return Case(switcher, o => true, action, false);
}
public static Switch Case<T>(this Switch switcher,
Action<T> action,
bool fallThrough) where T : class
{
return Case(switcher, o => true, action, fallThrough);
}
public static Switch Case<T>(this Switch switcher,
Func<T, bool> predicate,
Action<T> action) where T : class
{
return Case(switcher, predicate, action, false);
}
public static Switch Case<T>(this Switch s,
Func<T, bool> predicate,
Action<T> action,
bool fallThrough) where T : class
{
if (s == null)
{
return null;
}
var t = s.Target as T;
if (t == null)
{
return s;
}
if (!predicate(t))
{
return s;
}
action(t);
return fallThrough ? s : null;
}
public static void Default<T>(this Switch switcher,
Action<T> action) where T : class
{
if (switcher == null)
{
return;
}
var t = switcher.Target as T;
if (t == null)
{
return;
}
action(t);
}
}
Step 3: Finally, add an extension method for System.Object so that any object can call Switch() method.
public static class ObjectSwitchExtensions
{
public static Switch Switch(this object Object)
{
return new Switch(Object);
}
}
No comments:
Post a Comment