WhereEnumerable
using System; | |
using System.Collections; | |
using System.Collections.Generic; | |
using System.Text; | |
using Linq = System.Linq; | |
namespace ConsoleApplication5 | |
{ | |
class Program | |
{ | |
static void Main(string[] args) | |
{ | |
var s = | |
Linq.Enumerable.Range(1, 200) | |
.Where(x => x > 50) | |
.Where(x => x < 100); | |
var r = Linq.Enumerable.ToList(s); | |
} | |
} | |
class PredicateHolder<T> | |
{ | |
private Func<T, bool> predicate; | |
private PredicateHolder<T> next; | |
public PredicateHolder(Func<T, bool> predicate, PredicateHolder<T> next = null) | |
{ | |
this.predicate = predicate; | |
this.next = next; | |
} | |
public bool Eval(T x) | |
{ | |
var ok = true; | |
var holder = this; | |
while (ok && holder != null) | |
{ | |
ok &= holder.predicate(x); | |
holder = holder.next; | |
} | |
return ok; | |
} | |
} | |
class WhereEnumerable<T> : IEnumerable<T> | |
{ | |
private IEnumerable<T> source; | |
private PredicateHolder<T> holder; | |
public WhereEnumerable(IEnumerable<T> source, PredicateHolder<T> holder) | |
{ | |
this.source = source; | |
this.holder = holder; | |
} | |
public WhereEnumerable<T> Where(Func<T, bool> extraPredicate) | |
{ | |
return new WhereEnumerable<T>(source, new PredicateHolder<T>(extraPredicate, holder)); | |
} | |
public IEnumerator<T> GetEnumerator() | |
{ | |
foreach (var item in source) | |
{ | |
if (holder.Eval(item)) | |
yield return item; | |
} | |
} | |
IEnumerator IEnumerable.GetEnumerator() | |
{ | |
return GetEnumerator(); | |
} | |
} | |
static class Extensions | |
{ | |
public static IEnumerable<T> Where<T>(this IEnumerable<T> enumerable, Func<T, bool> predicate) | |
{ | |
var whereEnumerable = enumerable as WhereEnumerable<T>; | |
return whereEnumerable != null | |
? whereEnumerable.Where(predicate) | |
: new WhereEnumerable<T>(enumerable, new PredicateHolder<T>(predicate)); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment