Skip to content

Instantly share code, notes, and snippets.

@Majiir
Forked from anonymous/DisposableMemoize.cs
Last active August 29, 2015 14:24
Show Gist options
  • Save Majiir/254d64119b1260e06133 to your computer and use it in GitHub Desktop.
Save Majiir/254d64119b1260e06133 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
namespace EnumerableExtensions
{
public interface IDisposableEnumerable<T> : IDisposable, IEnumerable<T> { }
public static class EnumerableExtensions
{
public static IDisposableEnumerable<T> Disposer<T>(this IEnumerable<T> seq) where T : IDisposable
{
return new EnumerableDisposer<T>(seq);
}
public static IEnumerable<T> Memoize<T>(this IEnumerable<T> seq)
{
return new MemoizedEnumerable<T>(seq);
}
private class EnumerableDisposer<T> : IDisposableEnumerable<T> where T : IDisposable
{
private IEnumerable<T> seq;
public EnumerableDisposer(IEnumerable<T> seq)
{
if (seq == null) { throw new ArgumentNullException("seq"); }
this.seq = seq.Memoize();
}
public void Dispose()
{
foreach (var item in seq)
{
item.Dispose();
}
}
public IEnumerator<T> GetEnumerator()
{
return seq.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
private class MemoizedEnumerable<T> : IEnumerable<T>
{
private IEnumerable<T> seq;
private IEnumerator<T> iterator = null;
private readonly List<T> items = new List<T>();
public MemoizedEnumerable(IEnumerable<T> seq)
{
if (seq == null) { throw new ArgumentNullException("seq"); }
this.seq = seq;
}
public IEnumerator<T> GetEnumerator()
{
var index = 0;
while (true)
{
if (index < items.Count)
{
yield return items[index];
index++;
}
else if (seq != null)
{
if (iterator == null)
{
iterator = seq.GetEnumerator();
}
if (iterator.MoveNext())
{
items.Add(iterator.Current);
}
else
{
seq = null;
iterator.Dispose();
iterator = null;
}
}
else
{
yield break;
}
}
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment