You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.8 KiB
69 lines
1.8 KiB
5 years ago
|
// Needed for NET40
|
||
|
#if !NET_4_6
|
||
|
using System;
|
||
|
using System.Collections;
|
||
|
using System.Collections.Generic;
|
||
|
|
||
|
using LinqInternal.Core;
|
||
|
|
||
|
namespace LinqInternal.Collections.Specialized
|
||
|
{
|
||
|
internal class EnumerableFromDelegate<T> : IEnumerable<T>
|
||
|
{
|
||
|
private readonly Func<IEnumerator<T>> _getEnumerator;
|
||
|
|
||
|
public EnumerableFromDelegate(Func<IEnumerator> getEnumerator)
|
||
|
{
|
||
|
// Specify the type arguments explicitly
|
||
|
_getEnumerator = getEnumerator.ChainConversion<IEnumerator, IEnumerator<T>>(ConvertEnumerator);
|
||
|
}
|
||
|
|
||
|
public IEnumerator<T> GetEnumerator()
|
||
|
{
|
||
|
return _getEnumerator.Invoke();
|
||
|
}
|
||
|
|
||
|
IEnumerator IEnumerable.GetEnumerator()
|
||
|
{
|
||
|
return _getEnumerator.Invoke();
|
||
|
}
|
||
|
|
||
|
private static IEnumerator<T> ConvertEnumerator(IEnumerator enumerator)
|
||
|
{
|
||
|
if (enumerator == null)
|
||
|
{
|
||
|
return null;
|
||
|
}
|
||
|
var genericEnumerator = enumerator as IEnumerator<T>;
|
||
|
if (genericEnumerator != null)
|
||
|
{
|
||
|
return genericEnumerator;
|
||
|
}
|
||
|
return ConvertEnumeratorExtracted(enumerator);
|
||
|
}
|
||
|
|
||
|
private static IEnumerator<T> ConvertEnumeratorExtracted(IEnumerator enumerator)
|
||
|
{
|
||
|
try
|
||
|
{
|
||
|
while (enumerator.MoveNext())
|
||
|
{
|
||
|
var element = enumerator.Current;
|
||
|
if (element is T)
|
||
|
{
|
||
|
yield return (T)element;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
finally
|
||
|
{
|
||
|
var disposable = enumerator as IDisposable;
|
||
|
if (disposable != null)
|
||
|
{
|
||
|
disposable.Dispose();
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif
|