He venido con una pequeña extensión cuando rápidamente quiero probar/captar cada iteración de un IEnumerable<T>
Uso
public void Test()
{
List<string> completedProcesses = initialEnumerable
.SelectTry(x => RiskyOperation(x))
.OnCaughtException(exception => { _logger.Error(exception); return null; })
.Where(x => x != null) // filter the ones which failed
.ToList();
}
La extensión
public static class OnCaughtExceptionExtension
{
public static IEnumerable<SelectTryResult<TSource, TResult>> SelectTry<TSource, TResult>(this IEnumerable<TSource> enumerable, Func<TSource, TResult> selector)
{
foreach (TSource element in enumerable)
{
SelectTryResult<TSource, TResult> returnedValue;
try
{
returnedValue = new SelectTryResult<TSource, TResult>(element, selector(element), null);
}
catch (Exception ex)
{
returnedValue = new SelectTryResult<TSource, TResult>(element, default(TResult), ex);
}
yield return returnedValue;
}
}
public static IEnumerable<TResult> OnCaughtException<TSource, TResult>(this IEnumerable<SelectTryResult<TSource, TResult>> enumerable, Func<Exception, TResult> exceptionHandler)
{
return enumerable.Select(x => x.CaughtException == null ? x.Result : exceptionHandler(x.CaughtException));
}
public static IEnumerable<TResult> OnCaughtException<TSource, TResult>(this IEnumerable<SelectTryResult<TSource, TResult>> enumerable, Func<TSource, Exception, TResult> exceptionHandler)
{
return enumerable.Select(x => x.CaughtException == null ? x.Result : exceptionHandler(x.Source, x.CaughtException));
}
public class SelectTryResult<TSource,TResult>
{
internal SelectTryResult(TSource source, TResult result, Exception exception)
{
Source = source;
Result = result;
CaughtException = exception;
}
public TSource Source { get; private set; }
public TResult Result { get; private set; }
public Exception CaughtException { get; private set; }
}
}
Podríamos finalmente ir un poco más por tener una extensión SkipOnException
, aceptando opcionalmente un manejador de excepciones por ejemplo.
¿Qué considera un abuso de excepción? En mi lógica comercial, tengo un método para calcular el salario de un empleado. Hay varias cosas que pueden salir mal, como que el empleado no tenga un conjunto de sueldos. Hice una excepción personalizada que puedo lanzar y atrapar en mi controlador y poner en mi modelo de vista. ¿Eso es malo? – Pluc
@Pluc: ¿Se supone * que el empleado * tenga un salario establecido? Si es así, el hecho de que falte suena excepcional. Si se espera algo, probablemente no use excepciones para manejarlo. –