main
1namespace utility
2{
3 using System;
4 using System.Collections.Generic;
5
6 public interface IVisitor<T>
7 {
8 void Visit(T item);
9 }
10
11 public interface IVisitable<T>
12 {
13 void Accept(IVisitor<T> visitor);
14 }
15
16 public interface IValueReturningVisitor<T, TResult> : IVisitor<T>
17 {
18 TResult Result();
19 }
20
21 public static class Visiting
22 {
23 public static TResult AcceptAndReturnResultFrom<T, TResult>(this IVisitable<T> visitable, IValueReturningVisitor<T, TResult> visitor)
24 {
25 visitable.Accept(visitor);
26 return visitor.Result();
27 }
28
29 public static IEnumerable<T> Collect<T>( this IVisitable<T> visitable, Func<T, bool> predicate)
30 {
31 return new Collectable<T>(predicate).CollectFrom(visitable);
32 }
33 }
34
35 public interface ICollectable<T>
36 {
37 IEnumerable<T> CollectFrom(IVisitable<T> visitable);
38 }
39
40 public class Collectable<T> : ICollectable<T>
41 {
42 Func<T, bool> predicate;
43
44 public Collectable(Func<T, bool> predicate)
45 {
46 this.predicate = predicate;
47 }
48
49 public IEnumerable<T> CollectFrom(IVisitable<T> visitable)
50 {
51 var results = new List<T>();
52 visitable.Accept(new AnonymousVisitor<T>(item =>
53 {
54 if(predicate(item)) results.Add(item);
55 }));
56 return results;
57 }
58 }
59
60 public class AnonymousVisitor<T> : IVisitor<T>
61 {
62 Action<T> visitor;
63
64 public AnonymousVisitor(Action<T> visitor)
65 {
66 this.visitor = visitor;
67 }
68
69 public void Visit(T item)
70 {
71 visitor(item);
72 }
73 }
74}