Пример #1
0
        public void DisposeAfterEnumeration(int sourceLength, int subLength)
        {
            int sourceState = 0;
            int subIndex    = 0; // Index within the arrays the sub-collection is supposed to be at.

            int[] subState = new int[sourceLength];

            bool sourceDisposed = false;

            bool[] subCollectionDisposed = new bool[sourceLength];

            var source = new DelegateIterator <int>(
                moveNext: () => ++ sourceState <= sourceLength,
                current: () => 0,
                dispose: () => sourceDisposed = true);

            var subCollection = new DelegateIterator <int>(
                moveNext: () => ++ subState[subIndex] <= subLength,       // Return true `subLength` times.
                current: () => subState[subIndex],
                dispose: () => subCollectionDisposed[subIndex++] = true); // Record that Dispose was called, and move on to the next index.

            var iterator = source.SelectMany(_ => subCollection);

            int index           = 0; // How much have we gone into the iterator?
            IEnumerator <int> e = iterator.GetEnumerator();

            using (e)
            {
                while (e.MoveNext())
                {
                    int item = e.Current;

                    Assert.Equal(subState[subIndex], item); // Verify Current.
                    Assert.Equal(index / subLength, subIndex);

                    Assert.False(sourceDisposed); // Not yet.

                    // This represents whehter the sub-collection we're iterating thru right now
                    // has been disposed. Also not yet.
                    Assert.False(subCollectionDisposed[subIndex]);

                    // However, all of the sub-collections before us should have been disposed.
                    // Their indices should also be maxed out.
                    Assert.All(subState.Take(subIndex), s => Assert.Equal(subLength + 1, s));
                    Assert.All(subCollectionDisposed.Take(subIndex), t => Assert.True(t));

                    index++;
                }
            }

            Assert.True(sourceDisposed);
            Assert.Equal(sourceLength, subIndex);
            Assert.All(subState, s => Assert.Equal(subLength + 1, s));
            Assert.All(subCollectionDisposed, t => Assert.True(t));

            // Make sure the iterator's enumerator has been disposed properly.
            Assert.Equal(0, e.Current); // Default value.
            Assert.False(e.MoveNext());
            Assert.Equal(0, e.Current);
        }
Пример #2
0
        public void DisposeAfterEnumeration(int sourceLength, int subLength)
        {
            int sourceState = 0;
            int subIndex    = 0; // Index within the arrays the sub-collection is supposed to be at.

            int[] subState = new int[sourceLength];

            bool sourceDisposed = false;

            bool[] subCollectionDisposed = new bool[sourceLength];

            var source = new DelegateIterator <int>(
                moveNext: () => ++ sourceState <= sourceLength,
                current: () => 0,
                dispose: () => sourceDisposed = true);

            var subCollection = new DelegateIterator <int>(
                moveNext: () => ++ subState[subIndex] <= subLength,       // Return true `subLength` times.
                current: () => subState[subIndex],
                dispose: () => subCollectionDisposed[subIndex++] = true); // Record that Dispose was called, and move on to the next index.

            var iterator = source.SelectMany(_ => subCollection);

            int index           = 0; // How much have we gone into the iterator?
            IEnumerator <int> e = iterator.GetEnumerator();

            using (e)
            {
                while (e.MoveNext())
                {
                    int item = e.Current;

                    Assert.Equal(subState[subIndex], item); // Verify Current.
                    Assert.Equal(index / subLength, subIndex);

                    Assert.False(sourceDisposed); // Not yet.

                    // This represents whehter the sub-collection we're iterating thru right now
                    // has been disposed. Also not yet.
                    Assert.False(subCollectionDisposed[subIndex]);

                    // However, all of the sub-collections before us should have been disposed.
                    // Their indices should also be maxed out.
                    Assert.All(subState.Take(subIndex), s => Assert.Equal(subLength + 1, s));
                    Assert.All(subCollectionDisposed.Take(subIndex), t => Assert.True(t));

                    index++;
                }
            }

            Assert.True(sourceDisposed);
            Assert.Equal(sourceLength, subIndex);
            Assert.All(subState, s => Assert.Equal(subLength + 1, s));
            Assert.All(subCollectionDisposed, t => Assert.True(t));

            // .NET Core fixes an oversight where we wouldn't properly dispose
            // the SelectMany iterator. See https://github.com/dotnet/corefx/pull/13942.
            int expectedCurrent = PlatformDetection.IsFullFramework ? subLength : 0;

            Assert.Equal(expectedCurrent, e.Current);
            Assert.False(e.MoveNext());
            Assert.Equal(expectedCurrent, e.Current);
        }