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
// 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 |