Skip to content

Instantly share code, notes, and snippets.

@kana
Created May 26, 2011 10:15
Show Gist options
  • Save kana/992884 to your computer and use it in GitHub Desktop.
Save kana/992884 to your computer and use it in GitHub Desktop.
Learning LINQ by reimplementing
[TestClass()]
public class IMyEnumerableTest
{
[TestMethod()]
public void MyCastTest()
{
var xs = new [] {1, 2, 3}.MyCast();
Assert.IsTrue(xs is IMyEnumerable<Int32>);
var i = 1;
foreach (var x in xs)
{
Assert.AreEqual(i, x);
i++;
}
}
[TestMethod()]
public void MySkipTest()
{
var xs = new [] {1, 2, 3, 4, 5}.MyCast().MySkip(3);
var i = 4;
foreach (var x in xs)
{
Assert.AreEqual(i, x);
i++;
}
}
[TestMethod()]
public void MyTakeTest()
{
var xs = new [] {1, 2, 3, 4, 5}.MyCast().MyTake(3);
var i = 1;
foreach (var x in xs)
{
Assert.AreEqual(i, x);
i++;
}
Assert.AreEqual(4, i);
}
}
public static class MyEnumerable
{
public static IMyEnumerable<T> MyCast<T>(this IEnumerable<T> xs)
{
return new MyCastWrapper<T>(xs);
}
public static IMyEnumerable<T> MySkip<T>(this IMyEnumerable<T> xs, Int32 count)
{
return new MySkipWrapper<T>(xs, count);
}
public static IMyEnumerable<T> MyTake<T>(this IMyEnumerable<T> xs, Int32 count)
{
return new MyTakeWrapper<T>(xs, count);
}
}
public interface IMyEnumerable<T> : IEnumerable<T>
{
IEnumerable<T> OriginalSequence {get;}
}
public class MyCastWrapper<T> : IMyEnumerable<T>
{
public IEnumerable<T> OriginalSequence {get; private set;}
public MyCastWrapper(IEnumerable<T> xs)
{
this.OriginalSequence = xs;
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return this.OriginalSequence.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return this.OriginalSequence.GetEnumerator();
}
}
public class MySkipWrapper<T> : IMyEnumerable<T>
{
public IEnumerable<T> OriginalSequence {get; private set;}
private IMyEnumerable<T> xs;
private Int32 count;
public MySkipWrapper(IMyEnumerable<T> xs, Int32 count)
{
this.OriginalSequence = xs.OriginalSequence;
this.xs = xs;
this.count = count;
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new MySkipEnumerator<T>(this.xs, this.count);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new MySkipEnumerator<T>(this.xs, this.count);
}
}
public class MySkipEnumerator<T> : IEnumerator<T>
{
private IMyEnumerable<T> xs;
private Int32 count;
private IEnumerator<T> e;
public MySkipEnumerator(IMyEnumerable<T> xs, Int32 count)
{
this.xs = xs;
this.count = count;
this.e = xs.OriginalSequence.GetEnumerator();
this.Reset();
}
public bool MoveNext()
{
return this.e.MoveNext();
}
T IEnumerator<T>.Current
{
get
{
return this.e.Current;
}
}
object IEnumerator.Current
{
get
{
return this.e.Current;
}
}
public void Reset()
{
this.e.Reset();
foreach (var _ in Enumerable.Range(1, this.count))
this.e.MoveNext();
}
public void Dispose()
{
this.e.Dispose();
}
}
public class MyTakeWrapper<T> : IMyEnumerable<T>
{
public IEnumerable<T> OriginalSequence {get; private set;}
private IMyEnumerable<T> xs;
private Int32 count;
public MyTakeWrapper(IMyEnumerable<T> xs, Int32 count)
{
this.OriginalSequence = xs.OriginalSequence;
this.xs = xs;
this.count = count;
}
IEnumerator<T> IEnumerable<T>.GetEnumerator()
{
return new MyTakeEnumerator<T>(this.xs, this.count);
}
IEnumerator IEnumerable.GetEnumerator()
{
return new MyTakeEnumerator<T>(this.xs, this.count);
}
}
public class MyTakeEnumerator<T> : IEnumerator<T>
{
private IMyEnumerable<T> xs;
private Int32 count;
private IEnumerator<T> e;
private Int32 i;
public MyTakeEnumerator(IMyEnumerable<T> xs, Int32 count)
{
this.xs = xs;
this.count = count;
this.e = xs.OriginalSequence.GetEnumerator();
// this.i = ...;
this.Reset();
}
public bool MoveNext()
{
this.i++;
return this.e.MoveNext() && this.i < this.count;
}
T IEnumerator<T>.Current
{
get
{
return this.e.Current;
}
}
object IEnumerator.Current
{
get
{
return this.e.Current;
}
}
public void Reset()
{
this.e.Reset();
this.i = -1;
}
public void Dispose()
{
this.e.Dispose();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment