/// <summary> /// Combine three <see cref="Errorable{T}"/> values and return a result. /// </summary> /// <remarks>Any errors already present are preserved.</remarks> /// <typeparam name="T">Type of value possibly present in <paramref name="first"/>.</typeparam> /// <typeparam name="A">Type of value possibly present in <paramref name="second"/>.</typeparam> /// <typeparam name="B">Type of value possibly present in <paramref name="third"/>.</typeparam> /// <typeparam name="R">Type of return value.</typeparam> /// <param name="first">First errorable value.</param> /// <param name="second">Second errorable value.</param> /// <param name="third">Third errorable value.</param> /// <param name="combinerFunc">Function to combine all three values when available.</param> /// <returns>An errorable containing either the result of combining both available values, /// or a combined set of errors.</returns> public static Errorable <R> Combine <T, A, B, R>( this Errorable <T> first, Errorable <A> second, Errorable <B> third, Func <T, A, B, R> combinerFunc) { if (first == null) { throw new ArgumentNullException(nameof(first)); } if (second == null) { throw new ArgumentNullException(nameof(second)); } if (third == null) { throw new ArgumentNullException(nameof(third)); } if (combinerFunc == null) { throw new ArgumentNullException(nameof(combinerFunc)); } if (first.HasValue && second.HasValue && third.HasValue) { return(Errorable.Success( combinerFunc(first.Value, second.Value, third.Value))); } var allErrors = first.Errors.Union(second.Errors) .Union(third.Errors); return(Errorable.Failure <R>(allErrors)); }
/// <summary> /// Combine two <see cref="Errorable{T}"/> values /// </summary> /// <typeparam name="T">Type of value possibly present in <paramref name="first"/>.</typeparam> /// <typeparam name="A">Type of value possibly present in <paramref name="second"/>.</typeparam> /// <param name="first">First errorable value.</param> /// <param name="second">Second errorable value.</param> /// <param name="whenSuccessful">Action to take when both values are available.</param> /// <param name="whenFailure">Action to take if either (or both) errorables have errors.</param> public static void Combine <T, A>( this Errorable <T> first, Errorable <A> second, Action <T, A> whenSuccessful, Action <IEnumerable <string> > whenFailure) { if (first == null) { throw new ArgumentNullException(nameof(first)); } if (second == null) { throw new ArgumentNullException(nameof(second)); } if (whenSuccessful == null) { throw new ArgumentNullException(nameof(whenSuccessful)); } if (whenFailure == null) { throw new ArgumentNullException(nameof(whenFailure)); } if (first.HasValue && second.HasValue) { whenSuccessful(first.Value, second.Value); } else { var allErrors = first.Errors.Union(second.Errors); whenFailure(allErrors); } }