WhereEnumerable
This file contains 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; | |
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