Skip to content

Instantly share code, notes, and snippets.

@uzzu
Last active August 29, 2015 14:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save uzzu/32f9d0bc401f6e219f01 to your computer and use it in GitHub Desktop.
Save uzzu/32f9d0bc401f6e219f01 to your computer and use it in GitHub Desktop.
C#でパターンマッチング
using System;
using System.Collections.Generic;
namespace CaseMatch
{
static partial class Case<T1>
{
public class ActionMatcher : IMatcher
{
class Pair : Case.PairBase<Func<T1, bool>, Action<T1>>
{
public Pair(Func<T1, bool> predicate, Action<T1> callback) : base(predicate, callback)
{
}
}
readonly List<Pair> pairs;
readonly Action<T1> defaultCallback;
public IMatcher When(T1 value, Action callback)
{
return When(a => object.Equals(a, value), a => callback());
}
public IMatcher When(T1 value, Action<T1> callback)
{
return When(a => object.Equals(a, value), callback);
}
public IMatcher When(Func<T1, bool> predicate, Action callback)
{
return When(predicate, a => callback());
}
public IMatcher When(Func<T1, bool> predicate, Action<T1> callback)
{
Case.ValidateWhenArguments(predicate, callback);
var copied = new List<Pair>(pairs);
copied.Add(new Pair(predicate, callback));
return new ActionMatcher(copied, defaultCallback);
}
public IMatcher Default(Action defaultCallback)
{
return Default(a => defaultCallback());
}
public IMatcher Default(Action<T1> defaultCallback)
{
return new ActionMatcher(pairs, defaultCallback);
}
public void Apply(T1 candidate1)
{
foreach (var pair in pairs)
{
if (pair.Predicate(candidate1))
{
pair.Callback(candidate1);
return;
}
}
if (defaultCallback != null)
{
defaultCallback(candidate1);
}
}
public ActionMatcher() : this(new List<Pair>(), null)
{
}
ActionMatcher(List<Pair> pairs, Action<T1> defaultCallback)
{
this.pairs = pairs;
this.defaultCallback = defaultCallback;
}
}
}
static partial class Case<T1, T2>
{
public class ActionMatcher : IMatcher
{
class Pair : Case.PairBase<Func<T1, T2, bool>, Action<T1, T2>>
{
public Pair(Func<T1, T2, bool> predicate, Action<T1, T2> callback) : base(predicate, callback)
{
}
}
readonly List<Pair> pairs;
readonly Action<T1, T2> defaultCallback;
public IMatcher When(T1 value1, T2 value2, Action callback)
{
return When((a, b) => object.Equals(a, value1) && object.Equals(b, value2), (a, b) => callback());
}
public IMatcher When(T1 value1, T2 value2, Action<T1, T2> callback)
{
return When((a, b) => object.Equals(a, value1) && object.Equals(b, value2), callback);
}
public IMatcher When(Func<T1, T2, bool> predicate, Action callback)
{
return When(predicate, (a, b) => callback());
}
public IMatcher When(Func<T1, T2, bool> predicate, Action<T1, T2> callback)
{
Case.ValidateWhenArguments(predicate, callback);
var copied = new List<Pair>(pairs);
copied.Add(new Pair(predicate, callback));
return new ActionMatcher(copied, defaultCallback);
}
public IMatcher Default(Action defaultCallback)
{
return Default((a, b) => defaultCallback());
}
public IMatcher Default(Action<T1, T2> defaultCallback)
{
return new ActionMatcher(pairs, defaultCallback);
}
public void Apply(T1 candidate1, T2 candidate2)
{
foreach (var pair in pairs)
{
if (pair.Predicate(candidate1, candidate2))
{
pair.Callback(candidate1, candidate2);
return;
}
}
if (defaultCallback != null)
{
defaultCallback(candidate1, candidate2);
}
}
public ActionMatcher() : this(new List<Pair>(), null)
{
}
ActionMatcher(List<Pair> pairs, Action<T1, T2> defaultCallback)
{
this.pairs = pairs;
this.defaultCallback = defaultCallback;
}
}
}
static partial class Case<T1, T2, T3>
{
public class ActionMatcher : IMatcher
{
class Pair : Case.PairBase<Func<T1, T2, T3, bool>, Action<T1, T2, T3>>
{
public Pair(Func<T1, T2, T3, bool> predicate, Action<T1, T2, T3> callback) : base(predicate, callback)
{
}
}
readonly List<Pair> pairs;
readonly Action<T1, T2, T3> defaultCallback;
public IMatcher When(T1 value1, T2 value2, T3 value3, Action callback)
{
return When(
(a, b, c) => object.Equals(a, value1) && object.Equals(b, value2) && object.Equals(c, value3),
(a, b, c) => callback()
);
}
public IMatcher When(T1 value1, T2 value2, T3 value3, Action<T1, T2, T3> callback)
{
return When(
(a, b, c) => object.Equals(a, value1) && object.Equals(b, value2) && object.Equals(c, value3),
callback
);
}
public IMatcher When(Func<T1, T2, T3, bool> predicate, Action callback)
{
return When(predicate, (a, b, c) => callback());
}
public IMatcher When(Func<T1, T2, T3, bool> predicate, Action<T1, T2, T3> callback)
{
Case.ValidateWhenArguments(predicate, callback);
var copied = new List<Pair>(pairs);
copied.Add(new Pair(predicate, callback));
return new ActionMatcher(copied, defaultCallback);
}
public IMatcher Default(Action defaultCallback)
{
return Default((a, b, c) => defaultCallback());
}
public IMatcher Default(Action<T1, T2, T3> defaultCallback)
{
return new ActionMatcher(pairs, defaultCallback);
}
public void Apply(T1 candidate1, T2 candidate2, T3 candidate3)
{
foreach (var pair in pairs)
{
if (pair.Predicate(candidate1, candidate2, candidate3))
{
pair.Callback(candidate1, candidate2, candidate3);
return;
}
}
if (defaultCallback != null)
{
defaultCallback(candidate1, candidate2, candidate3);
}
}
public ActionMatcher() : this(new List<Pair>(), null)
{
}
ActionMatcher(List<Pair> pairs, Action<T1, T2, T3> defaultCallback)
{
this.pairs = pairs;
this.defaultCallback = defaultCallback;
}
}
}
static partial class Case<T1, T2, T3, T4>
{
public class ActionMatcher : IMatcher
{
class Pair : Case.PairBase<Func<T1, T2, T3, T4, bool>, Action<T1, T2, T3, T4>>
{
public Pair(Func<T1, T2, T3, T4, bool> predicate, Action<T1, T2, T3, T4> callback) : base(
predicate,
callback)
{
}
}
readonly List<Pair> pairs;
readonly Action<T1, T2, T3, T4> defaultCallback;
public IMatcher When(T1 value1, T2 value2, T3 value3, T4 value4, Action callback)
{
return When(
(a, b, c, d) => object.Equals(a, value1)
&& object.Equals(b, value2)
&& object.Equals(c, value3)
&& object.Equals(d, value4),
(a, b, c, d) => callback()
);
}
public IMatcher When(T1 value1, T2 value2, T3 value3, T4 value4, Action<T1, T2, T3, T4> callback)
{
return When(
(a, b, c, d) => object.Equals(a, value1)
&& object.Equals(b, value2)
&& object.Equals(c, value3)
&& object.Equals(d, value4),
callback
);
}
public IMatcher When(Func<T1, T2, T3, T4, bool> predicate, Action callback)
{
return When(predicate, (a, b, c, d) => callback());
}
public IMatcher When(Func<T1, T2, T3, T4, bool> predicate, Action<T1, T2, T3, T4> callback)
{
Case.ValidateWhenArguments(predicate, callback);
var copied = new List<Pair>(pairs);
copied.Add(new Pair(predicate, callback));
return new ActionMatcher(copied, defaultCallback);
}
public IMatcher Default(Action defaultCallback)
{
return Default((a, b, c, d) => defaultCallback());
}
public IMatcher Default(Action<T1, T2, T3, T4> defaultCallback)
{
return new ActionMatcher(pairs, defaultCallback);
}
public void Apply(T1 candidate1, T2 candidate2, T3 candidate3, T4 candidate4)
{
foreach (var pair in pairs)
{
if (pair.Predicate(candidate1, candidate2, candidate3, candidate4))
{
pair.Callback(candidate1, candidate2, candidate3, candidate4);
return;
}
}
if (defaultCallback != null)
{
defaultCallback(candidate1, candidate2, candidate3, candidate4);
}
}
public ActionMatcher() : this(new List<Pair>())
{
}
ActionMatcher(List<Pair> pairs) : this(pairs, null)
{
}
ActionMatcher(List<Pair> pairs, Action<T1, T2, T3, T4> defaultCallback)
{
this.pairs = pairs;
this.defaultCallback = defaultCallback;
}
}
}
}
using System;
namespace CaseMatch
{
public static class CaseAction
{
#region Case`1.Action
public static Case<T1>.IMatcher When<T1>(T1 value1, Action callback) where T1 : IEquatable<T1>
{
return new Case<T1>.ActionMatcher().When(value1, callback);
}
public static Case<T1>.IMatcher When<T1>(T1 value1, Action<T1> callback) where T1 : IEquatable<T1>
{
return new Case<T1>.ActionMatcher().When(value1, callback);
}
public static Case<T1>.IMatcher When<T1>(Func<T1, bool> predicate, Action callback) where T1 : IEquatable<T1>
{
return new Case<T1>.ActionMatcher().When(predicate, callback);
}
public static Case<T1>.IMatcher When<T1>(Func<T1, bool> predicate, Action<T1> callback) where T1 : IEquatable<T1>
{
return new Case<T1>.ActionMatcher().When(predicate, callback);
}
#endregion
#region Case`2.Action
public static Case<T1, T2>.IMatcher When<T1, T2>(T1 value1, T2 value2, Action callback) where T1 : IEquatable<T1> where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ActionMatcher().When(value1, value2, callback);
}
public static Case<T1, T2>.IMatcher When<T1, T2>(T1 value1, T2 value2, Action<T1, T2> callback) where T1 : IEquatable<T1> where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ActionMatcher().When(value1, value2, callback);
}
public static Case<T1, T2>.IMatcher When<T1, T2>(Func<T1, T2, bool> predicate, Action callback) where T1 : IEquatable<T1> where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ActionMatcher().When(predicate, callback);
}
public static Case<T1, T2>.IMatcher When<T1, T2>(Func<T1, T2, bool> predicate, Action<T1, T2> callback) where T1 : IEquatable<T1> where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ActionMatcher().When(predicate, callback);
}
#endregion
#region Case`3.Action
public static Case<T1, T2, T3>.IMatcher When<T1, T2, T3>(T1 value1, T2 value2, T3 value3, Action callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ActionMatcher().When(value1, value2, value3, callback);
}
public static Case<T1, T2, T3>.IMatcher When<T1, T2, T3>(
T1 value1,
T2 value2,
T3 value3,
Action<T1, T2, T3> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ActionMatcher().When(value1, value2, value3, callback);
}
public static Case<T1, T2, T3>.IMatcher When<T1, T2, T3>(Func<T1, T2, T3, bool> predicate, Action callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ActionMatcher().When(predicate, callback);
}
public static Case<T1, T2, T3>.IMatcher When<T1, T2, T3>(
Func<T1, T2, T3, bool> predicate,
Action<T1, T2, T3> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ActionMatcher().When(predicate, callback);
}
#endregion
#region Case`4.Action
public static Case<T1, T2, T3, T4>.IMatcher When<T1, T2, T3, T4>(
T1 value1,
T2 value2,
T3 value3,
T4 value4,
Action callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ActionMatcher().When(value1, value2, value3, value4, callback);
}
public static Case<T1, T2, T3, T4>.IMatcher When<T1, T2, T3, T4>(
T1 value1,
T2 value2,
T3 value3,
T4 value4,
Action<T1, T2, T3, T4> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ActionMatcher().When(value1, value2, value3, value4, callback);
}
public static Case<T1, T2, T3, T4>.IMatcher When<T1, T2, T3, T4>(
Func<T1, T2, T3, T4, bool> predicate,
Action callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ActionMatcher().When(predicate, callback);
}
public static Case<T1, T2, T3, T4>.IMatcher When<T1, T2, T3, T4>(
Func<T1, T2, T3, T4, bool> predicate,
Action<T1, T2, T3, T4> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ActionMatcher().When(predicate, callback);
}
#endregion
}
public static class CaseReturns<TResult>
{
#region Case`1.Returns
public static Case<T1>.IResultMatcher<TResult> When<T1>(T1 value1, TResult result) where T1 : IEquatable<T1>
{
return new Case<T1>.ResultMatcher<TResult>().When(value1, result);
}
public static Case<T1>.IResultMatcher<TResult> When<T1>(T1 value1, Func<TResult> callback) where T1 : IEquatable<T1>
{
return new Case<T1>.ResultMatcher<TResult>().When(value1, callback);
}
public static Case<T1>.IResultMatcher<TResult> When<T1>(T1 value1, Func<T1, TResult> callback) where T1 : IEquatable<T1>
{
return new Case<T1>.ResultMatcher<TResult>().When(value1, callback);
}
public static Case<T1>.IResultMatcher<TResult> When<T1>(Func<T1, bool> predicate, TResult result) where T1 : IEquatable<T1>
{
return new Case<T1>.ResultMatcher<TResult>().When(predicate, result);
}
public static Case<T1>.IResultMatcher<TResult> When<T1>(Func<T1, bool> predicate, Func<TResult> callback) where T1 : IEquatable<T1>
{
return new Case<T1>.ResultMatcher<TResult>().When(predicate, callback);
}
public static Case<T1>.IResultMatcher<TResult> When<T1>(Func<T1, bool> predicate, Func<T1, TResult> callback) where T1 : IEquatable<T1>
{
return new Case<T1>.ResultMatcher<TResult>().When(predicate, callback);
}
#endregion
#region Case`2.Returns
public static Case<T1, T2>.IResultMatcher<TResult> When<T1, T2>(T1 value1, T2 value2, TResult result)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ResultMatcher<TResult>().When(value1, value2, result);
}
public static Case<T1, T2>.IResultMatcher<TResult> When<T1, T2>(T1 value1, T2 value2, Func<TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ResultMatcher<TResult>().When(value1, value2, callback);
}
public static Case<T1, T2>.IResultMatcher<TResult> When<T1, T2>(
T1 value1,
T2 value2,
Func<T1, T2, TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ResultMatcher<TResult>().When(value1, value2, callback);
}
public static Case<T1, T2>.IResultMatcher<TResult> When<T1, T2>(Func<T1, T2, bool> predicate, TResult result)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ResultMatcher<TResult>().When(predicate, result);
}
public static Case<T1, T2>.IResultMatcher<TResult> When<T1, T2>(
Func<T1, T2, bool> predicate,
Func<TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ResultMatcher<TResult>().When(predicate, callback);
}
public static Case<T1, T2>.IResultMatcher<TResult> When<T1, T2>(
Func<T1, T2, bool> predicate,
Func<T1, T2, TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
{
return new Case<T1, T2>.ResultMatcher<TResult>().When(predicate, callback);
}
#endregion
#region Case`3.Returns
public static Case<T1, T2, T3>.IResultMatcher<TResult> When<T1, T2, T3>(
T1 value1,
T2 value2,
T3 value3,
TResult result)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ResultMatcher<TResult>().When(value1, value2, value3, result);
}
public static Case<T1, T2, T3>.IResultMatcher<TResult> When<T1, T2, T3>(
T1 value1,
T2 value2,
T3 value3,
Func<TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ResultMatcher<TResult>().When(value1, value2, value3, callback);
}
public static Case<T1, T2, T3>.IResultMatcher<TResult> When<T1, T2, T3>(
T1 value1,
T2 value2,
T3 value3,
Func<T1, T2, T3, TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ResultMatcher<TResult>().When(value1, value2, value3, callback);
}
public static Case<T1, T2, T3>.IResultMatcher<TResult> When<T1, T2, T3>(
Func<T1, T2, T3, bool> predicate,
TResult result)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ResultMatcher<TResult>().When(predicate, result);
}
public static Case<T1, T2, T3>.IResultMatcher<TResult> When<T1, T2, T3>(
Func<T1, T2, T3, bool> predicate,
Func<TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ResultMatcher<TResult>().When(predicate, callback);
}
public static Case<T1, T2, T3>.IResultMatcher<TResult> When<T1, T2, T3>(
Func<T1, T2, T3, bool> predicate,
Func<T1, T2, T3, TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
{
return new Case<T1, T2, T3>.ResultMatcher<TResult>().When(predicate, callback);
}
#endregion
#region Case`4.Returns
public static Case<T1, T2, T3, T4>.IResultMatcher<TResult> When<T1, T2, T3, T4>(
T1 value1,
T2 value2,
T3 value3,
T4 value4,
TResult result)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ResultMatcher<TResult>().When(value1, value2, value3, value4, result);
}
public static Case<T1, T2, T3, T4>.IResultMatcher<TResult> When<T1, T2, T3, T4>(
T1 value1,
T2 value2,
T3 value3,
T4 value4,
Func<TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ResultMatcher<TResult>().When(value1, value2, value3, value4, callback);
}
public static Case<T1, T2, T3, T4>.IResultMatcher<TResult> When<T1, T2, T3, T4>(
T1 value1,
T2 value2,
T3 value3,
T4 value4,
Func<T1, T2, T3, T4, TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ResultMatcher<TResult>().When(value1, value2, value3, value4, callback);
}
public static Case<T1, T2, T3, T4>.IResultMatcher<TResult> When<T1, T2, T3, T4>(
Func<T1, T2, T3, T4, bool> predicate,
TResult result)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ResultMatcher<TResult>().When(predicate, result);
}
public static Case<T1, T2, T3, T4>.IResultMatcher<TResult> When<T1, T2, T3, T4>(
Func<T1, T2, T3, T4, bool> predicate,
Func<TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ResultMatcher<TResult>().When(predicate, callback);
}
public static Case<T1, T2, T3, T4>.IResultMatcher<TResult> When<T1, T2, T3, T4>(
Func<T1, T2, T3, T4, bool> predicate,
Func<T1, T2, T3, T4, TResult> callback)
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
return new Case<T1, T2, T3, T4>.ResultMatcher<TResult>().When(predicate, callback);
}
#endregion
}
public static class Case
{
internal class PairBase<TPredicate, TCallback>
{
public TPredicate Predicate { get; private set; }
public TCallback Callback { get; private set; }
public PairBase(TPredicate predicate, TCallback callback)
{
Predicate = predicate;
Callback = callback;
}
}
internal static void ValidateWhenArguments(object predicate, object callback)
{
if (predicate == null)
{
throw new ArgumentNullException("predicate");
}
if (callback == null)
{
throw new ArgumentNullException("callback");
}
}
static Case()
{
}
}
}
using System;
namespace CaseMatch
{
public static partial class Case<T1> where T1 : IEquatable<T1>
{
public interface IApplyer
{
void Apply(T1 candidate1);
}
public interface IApplyer<TResult>
{
TResult Apply(T1 candidate1);
}
public interface IMatcher : IApplyer
{
IMatcher When(T1 value, Action callback);
IMatcher When(T1 value, Action<T1> callback);
IMatcher When(Func<T1, bool> predicate, Action callback);
IMatcher When(Func<T1, bool> predicate, Action<T1> callback);
IMatcher Default(Action defaultCallback);
IMatcher Default(Action<T1> defaultCallback);
}
public interface IResultMatcher<TResult> : IApplyer<TResult>
{
IResultMatcher<TResult> When(T1 value, TResult result);
IResultMatcher<TResult> When(T1 value, Func<TResult> callback);
IResultMatcher<TResult> When(T1 value, Func<T1, TResult> callback);
IResultMatcher<TResult> When(Func<T1, bool> value, TResult result);
IResultMatcher<TResult> When(Func<T1, bool> value, Func<TResult> callback);
IResultMatcher<TResult> When(Func<T1, bool> predicate, Func<T1, TResult> callback);
IResultMatcher<TResult> Default(TResult defaultResult);
IResultMatcher<TResult> Default(Func<TResult> defaultCallback);
IResultMatcher<TResult> Default(Func<T1, TResult> defaultCallback);
}
}
public static partial class Case<T1, T2> where T1 : IEquatable<T1> where T2 : IEquatable<T2>
{
public interface IApplyer
{
void Apply(T1 candidate1, T2 candidate2);
}
public interface IApplyer<TResult>
{
TResult Apply(T1 candidate1, T2 candidate2);
}
public interface IMatcher : IApplyer
{
IMatcher When(T1 value1, T2 value2, Action callback);
IMatcher When(T1 value1, T2 value2, Action<T1, T2> callback);
IMatcher When(Func<T1, T2, bool> predicate, Action callback);
IMatcher When(Func<T1, T2, bool> predicate, Action<T1, T2> callback);
IMatcher Default(Action defaultCallback);
IMatcher Default(Action<T1, T2> defaultCallback);
}
public interface IResultMatcher<TResult> : IApplyer<TResult>
{
IResultMatcher<TResult> When(T1 value1, T2 value2, TResult result);
IResultMatcher<TResult> When(T1 value1, T2 value2, Func<TResult> callback);
IResultMatcher<TResult> When(T1 value1, T2 value2, Func<T1, T2, TResult> callback);
IResultMatcher<TResult> When(Func<T1, T2, bool> predicate, TResult result);
IResultMatcher<TResult> When(Func<T1, T2, bool> predicate, Func<TResult> callback);
IResultMatcher<TResult> When(Func<T1, T2, bool> predicate, Func<T1, T2, TResult> callback);
IResultMatcher<TResult> Default(TResult defaultResult);
IResultMatcher<TResult> Default(Func<TResult> defaultCallback);
IResultMatcher<TResult> Default(Func<T1, T2, TResult> defaultCallback);
}
}
public static partial class Case<T1, T2, T3> where T1 : IEquatable<T1> where T2 : IEquatable<T2> where T3 : IEquatable<T3>
{
public interface IApplyer
{
void Apply(T1 candidate1, T2 candidate2, T3 candidate3);
}
public interface IApplyer<TResult>
{
TResult Apply(T1 candidate1, T2 candidate2, T3 candidate3);
}
public interface IMatcher : IApplyer
{
IMatcher When(T1 value1, T2 value2, T3 value3, Action callback);
IMatcher When(T1 value1, T2 value2, T3 value3, Action<T1, T2, T3> callback);
IMatcher When(Func<T1, T2, T3, bool> predicate, Action callback);
IMatcher When(Func<T1, T2, T3, bool> predicate, Action<T1, T2, T3> callback);
IMatcher Default(Action defaultCallback);
IMatcher Default(Action<T1, T2, T3> defaultCallback);
}
public interface IResultMatcher<TResult> : IApplyer<TResult>
{
IResultMatcher<TResult> When(T1 value1, T2 value2, T3 value3, TResult result);
IResultMatcher<TResult> When(T1 value1, T2 value2, T3 value3, Func<TResult> callback);
IResultMatcher<TResult> When(T1 value, T2 value2, T3 value3, Func<T1, T2, T3, TResult> callback);
IResultMatcher<TResult> When(Func<T1, T2, T3, bool> predicate, TResult result);
IResultMatcher<TResult> When(Func<T1, T2, T3, bool> predicate, Func<TResult> calllback);
IResultMatcher<TResult> When(Func<T1, T2, T3, bool> predicate, Func<T1, T2, T3, TResult> callback);
IResultMatcher<TResult> Default(TResult defaultResult);
IResultMatcher<TResult> Default(Func<TResult> defaultCallback);
IResultMatcher<TResult> Default(Func<T1, T2, T3, TResult> defaultCallback);
}
}
public static partial class Case<T1, T2, T3, T4>
where T1 : IEquatable<T1>
where T2 : IEquatable<T2>
where T3 : IEquatable<T3>
where T4 : IEquatable<T4>
{
public interface IApplyer
{
void Apply(T1 candidate1, T2 candidate2, T3 candidate3, T4 candidate4);
}
public interface IApplyer<TResult>
{
TResult Apply(T1 candidate1, T2 candidate2, T3 candidate3, T4 candidate4);
}
public interface IMatcher : IApplyer
{
IMatcher When(T1 value1, T2 value2, T3 value3, T4 value4, Action callback);
IMatcher When(T1 value1, T2 value2, T3 value3, T4 value4, Action<T1, T2, T3, T4> callback);
IMatcher When(Func<T1, T2, T3, T4, bool> predicate, Action callback);
IMatcher When(Func<T1, T2, T3, T4, bool> predicate, Action<T1, T2, T3, T4> callback);
IMatcher Default(Action defaultCallback);
IMatcher Default(Action<T1, T2, T3, T4> defaultCallback);
}
public interface IResultMatcher<TResult> : IApplyer<TResult>
{
IResultMatcher<TResult> When(T1 value1, T2 value2, T3 value3, T4 value4, TResult result);
IResultMatcher<TResult> When(T1 value1, T2 value2, T3 value3, T4 value4, Func<TResult> callback);
IResultMatcher<TResult> When(
T1 value1,
T2 value2,
T3 value3,
T4 value4,
Func<T1, T2, T3, T4, TResult> callback);
IResultMatcher<TResult> When(Func<T1, T2, T3, T4, bool> predicate, TResult result);
IResultMatcher<TResult> When(Func<T1, T2, T3, T4, bool> predicate, Func<TResult> callback);
IResultMatcher<TResult> When(Func<T1, T2, T3, T4, bool> predicate, Func<T1, T2, T3, T4, TResult> callback);
IResultMatcher<TResult> Default(TResult defaultResult);
IResultMatcher<TResult> Default(Func<TResult> defaultCallback);
IResultMatcher<TResult> Default(Func<T1, T2, T3, T4, TResult> defaultCallback);
}
}
}
using System;
using System.Collections.Generic;
namespace CaseMatch
{
static partial class Case<T1>
{
public class ResultMatcher<TResult> : IResultMatcher<TResult>
{
class Pair : Case.PairBase<Func<T1, bool>, Func<T1, TResult>>
{
public Pair(Func<T1, bool> predicate, Func<T1, TResult> callback) : base(predicate, callback)
{
}
}
readonly List<Pair> pairs;
readonly Func<T1, TResult> defaultCallback;
public IResultMatcher<TResult> When(T1 value, TResult result)
{
return When(a => object.Equals(a, value), () => result);
}
public IResultMatcher<TResult> When(T1 value, Func<TResult> callback)
{
return When(a => object.Equals(a, value), a => callback());
}
public IResultMatcher<TResult> When(T1 value, Func<T1, TResult> callback)
{
return When(a => object.Equals(a, value), callback);
}
public IResultMatcher<TResult> When(Func<T1, bool> predicate, TResult result)
{
return When(predicate, a => result);
}
public IResultMatcher<TResult> When(Func<T1, bool> predicate, Func<TResult> callback)
{
return When(predicate, a => callback());
}
public IResultMatcher<TResult> When(Func<T1, bool> predicate, Func<T1, TResult> callback)
{
Case.ValidateWhenArguments(predicate, callback);
var copied = new List<Pair>(pairs);
copied.Add(new Pair(predicate, callback));
return new ResultMatcher<TResult>(copied, defaultCallback);
}
public IResultMatcher<TResult> Default(TResult defaultValue)
{
return Default(a => defaultValue);
}
public IResultMatcher<TResult> Default(Func<TResult> defaultCallback)
{
return Default(a => defaultCallback());
}
public IResultMatcher<TResult> Default(Func<T1, TResult> defaultCallback)
{
return new ResultMatcher<TResult>(pairs, defaultCallback);
}
public TResult Apply(T1 candidate1)
{
foreach (var pair in pairs)
{
if (pair.Predicate(candidate1))
{
return pair.Callback(candidate1);
}
}
if (defaultCallback != null)
{
return defaultCallback(candidate1);
}
return default(TResult);
}
public ResultMatcher() : this(new List<Pair>(), null)
{
}
ResultMatcher(List<Pair> pairs, Func<T1, TResult> defaultCallback)
{
this.pairs = pairs;
this.defaultCallback = defaultCallback;
}
}
}
static partial class Case<T1, T2>
{
public class ResultMatcher<TResult> : IResultMatcher<TResult>
{
class Pair : Case.PairBase<Func<T1, T2, bool>, Func<T1, T2, TResult>>
{
public Pair(Func<T1, T2, bool> predicate, Func<T1, T2, TResult> callback) : base(predicate, callback)
{
}
}
readonly List<Pair> pairs;
readonly Func<T1, T2, TResult> defaultCallback;
public IResultMatcher<TResult> When(T1 value1, T2 value2, TResult result)
{
return When((a, b) => object.Equals(a, value1) && object.Equals(b, value2), (a, b) => result);
}
public IResultMatcher<TResult> When(T1 value1, T2 value2, Func<TResult> callback)
{
return When((a, b) => object.Equals(a, value1) && object.Equals(b, value2), (a, b) => callback());
}
public IResultMatcher<TResult> When(T1 value1, T2 value2, Func<T1, T2, TResult> callback)
{
return When((a, b) => object.Equals(a, value1) && object.Equals(b, value2), callback);
}
public IResultMatcher<TResult> When(Func<T1, T2, bool> predicate, TResult result)
{
return When(predicate, (a, b) => result);
}
public IResultMatcher<TResult> When(Func<T1, T2, bool> predicate, Func<TResult> callback)
{
return When(predicate, (a, b) => callback());
}
public IResultMatcher<TResult> When(Func<T1, T2, bool> predicate, Func<T1, T2, TResult> callback)
{
Case.ValidateWhenArguments(predicate, callback);
var copied = new List<Pair>(pairs);
copied.Add(new Pair(predicate, callback));
return new ResultMatcher<TResult>(copied, defaultCallback);
}
public IResultMatcher<TResult> Default(TResult defaultResult)
{
return Default((a, b) => defaultResult);
}
public IResultMatcher<TResult> Default(Func<TResult> defaultCallback)
{
return Default((a, b) => defaultCallback());
}
public IResultMatcher<TResult> Default(Func<T1, T2, TResult> defaultCallback)
{
return new ResultMatcher<TResult>(pairs, defaultCallback);
}
public TResult Apply(T1 candidate1, T2 candidate2)
{
foreach (var pair in pairs)
{
if (pair.Predicate(candidate1, candidate2))
{
return pair.Callback(candidate1, candidate2);
}
}
if (defaultCallback != null)
{
return defaultCallback(candidate1, candidate2);
}
return default(TResult);
}
public ResultMatcher() : this(new List<Pair>(), null)
{
}
ResultMatcher(List<Pair> pairs, Func<T1, T2, TResult> defaultCallback)
{
this.pairs = pairs;
this.defaultCallback = defaultCallback;
}
}
}
static partial class Case<T1, T2, T3>
{
public class ResultMatcher<TResult> : IResultMatcher<TResult>
{
class Pair : Case.PairBase<Func<T1, T2, T3, bool>, Func<T1, T2, T3, TResult>>
{
public Pair(Func<T1, T2, T3, bool> predicate, Func<T1, T2, T3, TResult> callback) : base(
predicate,
callback)
{
}
}
readonly List<Pair> pairs;
readonly Func<T1, T2, T3, TResult> defaultCallback;
public IResultMatcher<TResult> When(T1 value1, T2 value2, T3 value3, TResult result)
{
return When(
(a, b, c) => object.Equals(a, value1) && object.Equals(b, value2) && object.Equals(c, value3),
(a, b, c) => result
);
}
public IResultMatcher<TResult> When(T1 value1, T2 value2, T3 value3, Func<TResult> callback)
{
return When(
(a, b, c) => object.Equals(a, value1) && object.Equals(b, value2) && object.Equals(c, value3),
(a, b, c) => callback()
);
}
public IResultMatcher<TResult> When(T1 value1, T2 value2, T3 value3, Func<T1, T2, T3, TResult> callback)
{
return When(
(a, b, c) => object.Equals(a, value1) && object.Equals(b, value2) && object.Equals(c, value3),
callback
);
}
public IResultMatcher<TResult> When(Func<T1, T2, T3, bool> predicate, TResult result)
{
return When(predicate, (a, b, c) => result);
}
public IResultMatcher<TResult> When(Func<T1, T2, T3, bool> predicate, Func<TResult> callback)
{
return When(predicate, (a, b, c) => callback());
}
public IResultMatcher<TResult> When(Func<T1, T2, T3, bool> predicate, Func<T1, T2, T3, TResult> callback)
{
Case.ValidateWhenArguments(predicate, callback);
var copied = new List<Pair>(pairs);
copied.Add(new Pair(predicate, callback));
return new ResultMatcher<TResult>(copied, defaultCallback);
}
public IResultMatcher<TResult> Default(TResult defaultResult)
{
return Default((a, b, c) => defaultResult);
}
public IResultMatcher<TResult> Default(Func<TResult> defaultCallback)
{
return Default((a, b, c) => defaultCallback());
}
public IResultMatcher<TResult> Default(Func<T1, T2, T3, TResult> defaultCallback)
{
return new ResultMatcher<TResult>(pairs, defaultCallback);
}
public TResult Apply(T1 candidate1, T2 candidate2, T3 candidate3)
{
foreach (var pair in pairs)
{
if (pair.Predicate(candidate1, candidate2, candidate3))
{
return pair.Callback(candidate1, candidate2, candidate3);
}
}
if (defaultCallback != null)
{
return defaultCallback(candidate1, candidate2, candidate3);
}
return default(TResult);
}
public ResultMatcher() : this(new List<Pair>(), null)
{
}
ResultMatcher(List<Pair> pairs, Func<T1, T2, T3, TResult> defaultCallback)
{
this.pairs = pairs;
this.defaultCallback = defaultCallback;
}
}
}
static partial class Case<T1, T2, T3, T4>
{
public class ResultMatcher<TResult> : IResultMatcher<TResult>
{
class Pair : Case.PairBase<Func<T1, T2, T3, T4, bool>, Func<T1, T2, T3, T4, TResult>>
{
public Pair(Func<T1, T2, T3, T4, bool> predicate, Func<T1, T2, T3, T4, TResult> callback) : base(
predicate,
callback)
{
}
}
readonly List<Pair> pairs;
readonly Func<T1, T2, T3, T4, TResult> defaultCallback;
public IResultMatcher<TResult> When(T1 value1, T2 value2, T3 value3, T4 value4, TResult result)
{
return When(
(a, b, c, d) => object.Equals(a, value1)
&& object.Equals(b, value2)
&& object.Equals(c, value3)
&& object.Equals(d, value4),
(a, b, c, d) => result
);
}
public IResultMatcher<TResult> When(T1 value1, T2 value2, T3 value3, T4 value4, Func<TResult> callback)
{
return When(
(a, b, c, d) => object.Equals(a, value1)
&& object.Equals(b, value2)
&& object.Equals(c, value3)
&& object.Equals(d, value4),
(a, b, c, d) => callback()
);
}
public IResultMatcher<TResult> When(
T1 value1,
T2 value2,
T3 value3,
T4 value4,
Func<T1, T2, T3, T4, TResult> callback)
{
return When(
(a, b, c, d) => object.Equals(a, value1)
&& object.Equals(b, value2)
&& object.Equals(c, value3)
&& object.Equals(d, value4),
callback
);
}
public IResultMatcher<TResult> When(Func<T1, T2, T3, T4, bool> predicate, TResult result)
{
return When(predicate, (a, b, c, d) => result);
}
public IResultMatcher<TResult> When(Func<T1, T2, T3, T4, bool> predicate, Func<TResult> callback)
{
return When(predicate, (a, b, c, d) => callback());
}
public IResultMatcher<TResult> When(
Func<T1, T2, T3, T4, bool> predicate,
Func<T1, T2, T3, T4, TResult> callback)
{
Case.ValidateWhenArguments(predicate, callback);
var copied = new List<Pair>(pairs);
copied.Add(new Pair(predicate, callback));
return new ResultMatcher<TResult>(copied, defaultCallback);
}
public IResultMatcher<TResult> Default(TResult defaultResult)
{
return Default((a, b, c, d) => defaultResult);
}
public IResultMatcher<TResult> Default(Func<TResult> defaultCallback)
{
return Default((a, b, c, d) => defaultCallback());
}
public IResultMatcher<TResult> Default(Func<T1, T2, T3, T4, TResult> defaultCallback)
{
return new ResultMatcher<TResult>(pairs, defaultCallback);
}
public TResult Apply(T1 candidate1, T2 candidate2, T3 candidate3, T4 candidate4)
{
foreach (var pair in pairs)
{
if (pair.Predicate(candidate1, candidate2, candidate3, candidate4))
{
return pair.Callback(candidate1, candidate2, candidate3, candidate4);
}
}
if (defaultCallback != null)
{
return defaultCallback(candidate1, candidate2, candidate3, candidate4);
}
return default(TResult);
}
public ResultMatcher() : this(new List<Pair>(), null)
{
}
ResultMatcher(List<Pair> pairs, Func<T1, T2, T3, T4, TResult> defaultCallback)
{
this.pairs = pairs;
this.defaultCallback = defaultCallback;
}
}
}
}
using NUnit.Framework;
using System;
namespace CaseMatch
{
[TestFixture]
public class CaseTest
{
[TestCase(1, ExpectedResult = "hogehoge")]
[TestCase(2, ExpectedResult = "fugafuga")]
[TestCase(3, ExpectedResult = "piyopiyo")]
[TestCase(-1, ExpectedException = typeof(ArgumentException))]
public string TestCase1Action(int value)
{
var result = string.Empty;
Action throwException = () =>
{
throw new ArgumentException();
};
CaseAction
.When(1, () => result = "hogehoge")
.When(2, () => result = "fugafuga")
.When(3, () => result = "piyopiyo")
.Default(throwException)
.Apply(value);
return result;
}
[TestCase(1, ExpectedResult = "1")]
[TestCase(3, ExpectedResult = "Fizz")]
[TestCase(5, ExpectedResult = "Buzz")]
[TestCase(15, ExpectedResult = "FizzBuzz")]
[TestCase(100, ExpectedResult = "Buzz")]
[TestCase(-1, ExpectedException = typeof(ArgumentException))]
public string TestCase1Returns(int value)
{
Func<string> throwException = () =>
{
throw new ArgumentException();
};
return CaseReturns<string>
.When<int>(x => x % 3 == 0 && x % 5 == 0, "FizzBuzz")
.When(x => x % 3 == 0, "Fizz")
.When(x => x % 5 == 0, "Buzz")
.When(x => x >= 0, value.ToString())
.Default(throwException)
.Apply(value);
}
[TestCase(0, 0, ExpectedResult = "no-factor")]
[TestCase(1, 0, ExpectedResult = "factor-x: 1")]
[TestCase(0, 1, ExpectedResult = "factor-y: 1")]
[TestCase(1, 1, ExpectedResult = "factor-xy: 1, 1")]
[TestCase(-1, -1, ExpectedResult = "factor-xy: -1, -1")]
public string TestCase2Returns(int value1, int value2)
{
return CaseReturns<string>
.When(0, 0, "no-factor")
.When((x, y) => x != 0 && y == 0, string.Format("factor-x: {0}", value1))
.When((x, y) => x == 0 && y != 0, string.Format("factor-y: {0}", value2))
.Default(string.Format("factor-xy: {0}, {1}", value1, value2))
.Apply(value1, value2);
}
[TestCase(0, 0, 0, ExpectedResult = "no-factor")]
[TestCase(1, 0, 0, ExpectedResult = "factor-x: 1")]
[TestCase(1, 2, 0, ExpectedResult = "factor-xy: 1, 2")]
[TestCase(1, 0, 3, ExpectedResult = "factor-xz: 1, 3")]
[TestCase(0, 2, 0, ExpectedResult = "factor-y: 2")]
[TestCase(0, 2, 3, ExpectedResult = "factor-yz: 2, 3")]
[TestCase(0, 0, 3, ExpectedResult = "factor-z: 3")]
[TestCase(1, 2, 3, ExpectedResult = "factor-xyz: 1, 2, 3")]
public string TestCase3Returns(int value1, int value2, int value3)
{
return CaseReturns<string>
.When(0, 0, 0, "no-factor")
.When((x, y, z) => x != 0 && y == 0 && z == 0, string.Format("factor-x: {0}", value1))
.When((x, y, z) => x != 0 && y != 0 && z == 0, string.Format("factor-xy: {0}, {1}", value1, value2))
.When((x, y, z) => x != 0 && y == 0 && z != 0, string.Format("factor-xz: {0}, {1}", value1, value3))
.When((x, y, z) => x == 0 && y != 0 && z == 0, string.Format("factor-y: {0}", value2))
.When((x, y, z) => x == 0 && y != 0 && z != 0, string.Format("factor-yz: {0}, {1}", value2, value3))
.When((x, y, z) => x == 0 && y == 0 && z != 0, string.Format("factor-z: {0}", value3))
.Default(string.Format("factor-xyz: {0}, {1}, {2}", value1, value2, value3))
.Apply(value1, value2, value3);
}
[TestCase(0, 0, 0, 0, ExpectedResult = "no-factor")]
[TestCase(1, -1, 2, -2, ExpectedResult = "factor: (x = 1, y = -1, z = 2, w = -2)")]
public string TestCase4Returns(int value1, int value2, int value3, int value4)
{
return CaseReturns<string>
.When(0, 0, 0, 0, "no-factor")
.Default(string.Format("factor: (x = {0}, y = {1}, z = {2}, w = {3})", value1, value2, value3, value4))
.Apply(value1, value2, value3, value4);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment