Skip to content

Instantly share code, notes, and snippets.

@voroninp
Last active October 30, 2023 12:53
Show Gist options
  • Save voroninp/262f4c209c4ce21e858fdc92a60ffbe8 to your computer and use it in GitHub Desktop.
Save voroninp/262f4c209c4ce21e858fdc92a60ffbe8 to your computer and use it in GitHub Desktop.
Yield return inside try catch
public static class EnumerableExtensions
{
/// <summary>
/// Handles the exception and returns either new one (can be same as received) or <c>null</c> - which means exception is handled and should not be
/// thrown. Enumerations ends in any case.
/// </summary>
public static IEnumerable<T> Catching<T, TMoveNextException>(
this IEnumerable<T> seq,
Func<TMoveNextException, Exception?> catchOnMoveNext)
where TMoveNextException : Exception
{
seq.NotNull();
catchOnMoveNext.NotNull();
var enumerator = seq.GetEnumerator();
using (enumerator)
{
bool moved;
do
{
moved = false;
try
{
moved = enumerator.MoveNext();
}
catch (TMoveNextException ex)
{
var transforemdException = catchOnMoveNext(ex);
if (ReferenceEquals(ex, transforemdException))
{
throw;
}
if (transforemdException is not null)
{
throw transforemdException;
}
}
if (moved)
{
yield return enumerator.Current;
}
}
while (moved);
}
}
/// <summary>
/// Handles the exception and returns either new one (can be same as received) or <c>null</c> - which means exception is handled and should not be
/// thrown. Enumerations ends in any case.
/// </summary>
public static IEnumerable<T> Catching<T>(
this IEnumerable<T> seq,
Func<Exception, Exception?> catchOnMoveNext)
=>
seq.Catching<T, Exception>(catchOnMoveNext);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment