Created
November 6, 2014 15:50
-
-
Save sean-gilliam/db65ec4152c1ed8615d3 to your computer and use it in GitHub Desktop.
Fluent Type Switch
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
namespace Utilities | |
{ | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
public class Switch | |
{ | |
private readonly ICollection<Func<object, Action>> _cases; | |
private bool _defaultUsed; | |
public Switch(params Func<object, Action>[] cases) | |
{ | |
if (cases == null) | |
{ | |
_cases = Enumerable.Empty<Func<object, Action>>().ToList(); | |
return; | |
} | |
_cases = cases.ToList(); | |
} | |
public Switch Case<T>(Action<T> action) | |
{ | |
_cases.Add(o => o is T ? (Action)(() => action((T)o)) : (Action)null); | |
return this; | |
} | |
public Switch Default(Action action) | |
{ | |
if(_defaultUsed) | |
throw new InvalidOperationException("Default can only be used once"); | |
_defaultUsed = true; | |
Case<object>(x => action()); | |
return this; | |
} | |
public void Execute(object obj) | |
{ | |
var @case = _cases | |
.Select(f => f(obj)) | |
.FirstOrDefault(a => a != null); | |
if (@case != null) | |
{ | |
@case(); | |
} | |
} | |
} | |
} | |
=========================================================================== | |
Usage: // where the various Execute methods are part of the class | |
1) var @switch = new Switch() | |
.Case<Test1>(x => x.Execute("hello")) | |
.Case<Test2>(x => x.Execute("there")) | |
.Case<Test3>(x => x.Execute("want")) | |
.Case<Test4>(x => x.Execute("to")) | |
.Default(() => Console.WriteLine("party")); | |
var t2 = new Test2(); | |
@switch.Execute(t2); // should execute the second case | |
2) var @switch = new Switch() | |
.Case<Test1>(x => x.Execute("hello")) | |
.Case<Test2>(x => x.Execute("there")) | |
.Case<Test3>(x => x.Execute("want")) | |
.Case<Test4>(x => x.Execute("to")) | |
.Default(() => Console.WriteLine("party")); | |
var t2 = string.Empty; | |
@switch.Execute(t2); //Default should be executed | |
3) var @switch = new Switch() | |
.Case<Test1>(x => x.Execute("hello")) | |
.Case<Test2>(x => x.Execute("there")) | |
.Case<Test3>(x => x.Execute("want")) | |
.Case<Test4>(x => x.Execute("to")); | |
var t2 = string.Empty; | |
@switch.Execute(t2); //should fall through without executing anything |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment