这是我的尝试。我重新命名了界面,只是为了理解,因为我把它拼凑在一起了。
public interface IWhen<T> {
IThen<T> Then(Action<T> action);
}
public interface IThen<T> : IRun {
IWhen<T> When(Func<T, bool> test);
IRun Otherwise(Action<T> action);
}
public interface IRun {
void Run();
}
public interface IRule<T> {
Func<T, bool> Predicate { get; }
Action<T> Invoke { get; }
}
public class Rule<T> : IRule<T> {
public Rule(Func<T, bool> predicate, Action<T> action) {
this.Predicate = predicate;
this.Invoke = action;
}
public Func<T, bool> Predicate { get; private set; }
public Action<T> Invoke { get; private set; }
}
public class Then<T> : IThen<T> {
private Queue<IRule<T>> rules = new Queue<IRule<T>>();
private IEnumerable<T> source;
public Then(IEnumerable<T> source, Queue<IRule<T>> rules) {
this.source = source;
this.rules = rules;
}
public IWhen<T> When(Func<T, bool> test) {
var temp = new When<T>(source, test, rules);
return temp;
}
public void Run() {
foreach (var item in source) {
var rule = rules.FirstOrDefault(r => r.Predicate(item));
if (rule == null) continue;
rule.Invoke(item);
}
}
public IRun Otherwise(Action<T> action) {
var rule = new Rule<T>(s => true, action);
rules.Enqueue(rule);
return new Then<T>(source, rules);
}
}
public class When<T> : IWhen<T> {
private Queue<IRule<T>> rules;
private Func<T, bool> test;
private IEnumerable<T> source;
public When(IEnumerable<T> source, Func<T, bool> test, Queue<IRule<T>> rules = null) {
this.source = source;
this.test = test;
this.rules = rules ?? new Queue<IRule<T>>();
}
public IThen<T> Then(Action<T> action) {
var rule = new Rule<T>(test, action);
rules.Enqueue(rule);
var then = new Then<T>(source, rules);
return then;
}
}
然后,扩展方法看起来是这样开始的。
public static class EnumerableExtensions {
public static IWhen<T> When<T>(this IEnumerable<T> source, Func<T, bool> test) {
var temp = new When<T>(source, test);
return temp;
}
}
下面的例子
.Net Fiddle
public class Program {
public static void Main() {
Enumerable.Range(1, 10)
.When(i => i % 3 == 0).Then(i => Console.WriteLine("fizz"))
.When(i => i % 5 == 0).Then(i => Console.WriteLine("buzz"))
.Otherwise(i => Console.WriteLine(i))
.Run();
}
}
产生
1
2
fizz
4
buzz
fizz
7
8
fizz
buzz