/// <summary> /// Returns the specified collection while inserting the collection specified starting from the specified index. /// </summary> /// <param name="items">the collection to be inserted</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentOutOfRangeException"/> /// <exception cref="InvalidOperationException"/> public static IEnumerable EnumerableInsert(this IEnumerable source, int index, IEnumerable items) { Error.ThrowIfNull(source, nameof(source)); Error.ThrowIfBelowRange(index, nameof(index), 0); int counter = 0; using (DisposableEnumerator enumerator = new DisposableEnumerator(source.GetEnumerator())) { while (enumerator.MoveNext()) { if (counter == index) { foreach (object item in items) { yield return(item); } } yield return(enumerator.Current); ++counter; } } if (counter == index) { foreach (object item in items) { yield return(item); } } else if (counter < index) { Error.ThrowArgumentOutOfRange(nameof(index)); } }
/// <summary> /// Returns the sequence skipping the specified index. /// </summary> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentOutOfRangeException"/> public static IEnumerable SkipIndex(this IEnumerable source, int index) { Error.ThrowIfNull(source, nameof(source)); Error.ThrowIfBelowRange(index, nameof(index), 0); int currentIndex = -1; bool skipped = false; using DisposableEnumerator enumerator = new DisposableEnumerator(source.GetEnumerator()); while (enumerator.MoveNext()) { ++currentIndex; if (currentIndex != index) { yield return(enumerator.Current); } else { skipped = true; } } if (!skipped) { Error.ThrowArgumentOutOfRange(nameof(index)); } }
public static object FirstOrNull(this IEnumerable source) { if (source == null) { throw new ArgumentNullException("source"); } IList collection = source as IList; if (collection != null) { if (collection.Count > 0) { return(collection[0]); } } else { using (DisposableEnumerator enumerator = source.GetDisposableEnumerator()) { if (enumerator.MoveNext()) { return(enumerator.Current); } } } return(null); }
/// <summary> /// Returns the specified collection while inserting the item specified at the specified index. /// </summary> /// <param name="item">the item to be inserted</param> /// <exception cref="ArgumentNullException"/> /// <exception cref="ArgumentOutOfRangeException"/> /// <exception cref="InvalidOperationException"/> public static IEnumerable EnumerableInsert(this IEnumerable source, int index, object item) { Error.ThrowIfNull(source, nameof(source)); Error.ThrowIfBelowRange(index, nameof(index), 0); int counter = 0; using (DisposableEnumerator enumerator = new DisposableEnumerator(source.GetEnumerator())) { while (enumerator.MoveNext()) { if (counter == index) { yield return(item); } yield return(enumerator.Current); ++counter; } } if (counter == index) //Insert to the end - same as EnumerableAdd { yield return(item); } else if (counter < index) //Index was greater than the last index if the item was to be added to the end { Error.ThrowArgumentOutOfRange(nameof(index)); } }
public static object First(this IEnumerable source) { if (source == null) { throw new ArgumentNullException("source"); } IList collection = source as IList; if (collection != null) { if (collection.Count > 0) { return(collection[0]); } } else { using (DisposableEnumerator enumerator = source.GetDisposableEnumerator()) { if (enumerator.MoveNext()) { return(enumerator.Current); } } } throw new InvalidOperationException("Sequence contains no elements"); }
public static bool Any(this IEnumerable source) { Error.ThrowIfNull(source, nameof(source)); using DisposableEnumerator e = new DisposableEnumerator(source.GetEnumerator()); if (e.MoveNext()) { return(true); } return(false); }
public void TestExclusiveEmptyRemainer() { IEnumerable <int> sequence = new int[] { 0 }; IEnumerator <int> enumerator = new DisposableEnumerator(sequence.GetEnumerator()); enumerator.MoveNext(); var result = enumerator.ToEnumerable(includeCurrent: false); var expected = sequence.Skip(1); Assert.IsTrue(expected.SequenceEqual(result)); }
public static long LongCount(this IEnumerable source) { Error.ThrowIfNull(source, nameof(source)); long count = 0; using DisposableEnumerator e = new DisposableEnumerator(source.GetEnumerator()); checked { while (e.MoveNext()) { ++count; } } return(count); }
public static bool Any(this IEnumerable source) { if (source == null) { throw new ArgumentNullException("source"); } using (DisposableEnumerator enumerator = source.GetDisposableEnumerator()) { if (enumerator.MoveNext()) { return(true); } } return(false); }
public void UndisposableEnumerator_IsDisposalIgnored() { //Arrange DisposableEnumerator enumerator = new DisposableEnumerator(new UndisposableEnumerator()); enumerator.Dispose(); //Act void actual() { enumerator.Reset(); } //Assert Assert.DoesNotThrow(actual); }
public void DisposedEnumerator_IsDisposed() { //Arrange DisposableEnumerator enumerator = new DisposableEnumerator(new DisposedEnumerator <SimpleObject>()); enumerator.Dispose(); //Act void actual() { enumerator.Reset(); } //Assert Assert.Throws <ObjectDisposedException>(actual); }
public static int Count(this IEnumerable source) { Error.ThrowIfNull(source, nameof(source)); if (source is ICollection collection) { return(collection.Count); } int count = 0; using DisposableEnumerator e = new DisposableEnumerator(source.GetEnumerator()); checked { while (e.MoveNext()) { ++count; } } return(count); }
public void TestCancelStuckEnumerable() { var lastValue = -1; var cancellation = new Cancellation(); var stickWhileEvent = new ManualResetEvent(false); var ints = new DisposableEnumerator<int>(StuckDownEnumerable(stickWhileEvent)); var select = ints .SelectParallely(i => Interlocked.Exchange(ref lastValue, i), cancellation); new Thread(() => { Thread.Sleep(100); cancellation.Cancel(); }).Start(); AssertEx.Throws<OperationCanceledException>(() => select.AsEnumerable().ToList()); Assert.AreEqual(1, lastValue); stickWhileEvent.Set(); Thread.Sleep(100); Assert.IsTrue(ints.IsDisposed); }
public EnumerableWithDisposableEnumerator(IEnumerable <int> sequence) { Contract.Requires(sequence != null); this.enumerator = new DisposableEnumerator(sequence.GetEnumerator()); }
public void TestDisposingEnumerable() { var obj = new DisposableEnumerator<int>(Enumerable.Range(0, 11)); Assert.IsFalse(obj.IsDisposed); var list = obj.SelectParallely(i => i).AsEnumerable().ToList(); var sum = list.Sum(); Assert.AreEqual(55, sum); Thread.Sleep(100); Assert.IsTrue(obj.IsDisposed); }
public void TestEnumerableThreadSafeWrapper() { var stickWhileEvent = new ManualResetEvent(false); var enumerator = new DisposableEnumerator<int>(StuckDownEnumerable(stickWhileEvent)); var wrapper = new EnumerableThreadSafeWrapper<int>(enumerator); var result = new List<int>(); new Thread(() => { int i; if (wrapper.TryGetNext(out i)) lock (result) result.Add(i); }).Start(); new Thread(() => { int i; if (wrapper.TryGetNext(out i)) lock (result) result.Add(i); }).Start(); Thread.Sleep(100); Assert.AreEqual(1, result.Count); Assert.AreEqual(1, result[0]); wrapper.Dispose(); // Source Enumerator is stuck down but Dispose returns immediately // and real disposal is schedulled on the ending of last TryGetNex() int item; AssertEx.Throws<ObjectDisposedException>(() => wrapper.TryGetNext(out item)); stickWhileEvent.Set(); Thread.Sleep(100); // 2nd TryGetNext was invoked before Dispose() and should finish successfully Assert.AreEqual(2, result.Count); Assert.AreEqual(2, result[1]); AssertEx.Throws<ObjectDisposedException>(() => wrapper.TryGetNext(out item)); }