Created
May 26, 2011 10:15
-
-
Save kana/992884 to your computer and use it in GitHub Desktop.
Learning LINQ by reimplementing
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
[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