Last active
August 11, 2017 06:54
-
-
Save spirit11/ac6af74e86663a6bd11a8489862e4925 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
using System; | |
/// <summary> | |
/// Extension class for pattern matching workaround in older version of C# | |
/// </summary> | |
public static class PatternMatchExtension | |
{ | |
public interface IMatcher<T> | |
where T : class | |
{ | |
/// <summary> | |
/// Invokes Action when pattern object is of type TV | |
/// </summary> | |
/// <typeparam name="TV">subtype of T</typeparam> | |
/// <param name="Action">Action to invoke</param> | |
/// <returns></returns> | |
IMatcher<T> Case<TV>(Action<TV> Action) | |
where TV : T; | |
/// <summary> | |
/// Invokes Action when other matches hasn't succeed | |
/// </summary> | |
/// <param name="Action">Action to invoke</param> | |
void Default(Action<T> Action); | |
} | |
/// <summary> | |
/// Starts the chain of matching cases. Call Case and Default methods of returned object. | |
/// </summary> | |
/// <typeparam name="T">Object type</typeparam> | |
/// <param name="Object">Object for pattern matching</param> | |
/// <returns>Pattern matching monad <see cref="IMatcher{T}"/></returns> | |
public static IMatcher<T> Match<T>(this T Object) | |
where T : class | |
{ | |
return new Matcher<T>(Object); | |
} | |
private class Matcher<T> : IMatcher<T> | |
where T : class | |
{ | |
public Matcher(T Object) | |
{ | |
this.obj = Object; | |
} | |
public IMatcher<T> Case<TV>(Action<TV> Action) | |
where TV : T | |
{ | |
if (obj is TV) | |
{ | |
Action((TV)obj); | |
return new Bypass<T>(); | |
} | |
return this; | |
} | |
public void Default(Action<T> Action) | |
{ | |
Action(obj); | |
} | |
private T obj; | |
} | |
private class Bypass<T> : IMatcher<T> | |
where T : class | |
{ | |
public IMatcher<T> Case<TV>(Action<TV> Action) | |
where TV : T | |
{ | |
return this; | |
} | |
public void Default(Action<T> Action) | |
{ | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment