/// <summary> /// The <see cref="AggregateException"/> is re-created, with the optional <c>message</c>. Note that the /// incoming <see cref="AggregateException"/> may be null: if so, a new instance is created. The <c>error</c> /// argument is inserted into the <see cref="AggregateException.InnerExceptions"/> list at the beginning. If /// the <c>message</c> is not null, it is set as the <see cref="Exception.Message"/>; and if null, the /// <c>error</c>'s Message is used. /// </summary> /// <typeparam name="TAggregateException">Your <see cref="AggregateException"/> type.</typeparam> /// <param name="aggregateException">Notice: can be null.</param> /// <param name="constructor">Not null. This must construct your new <see cref="TAggregateException"/> /// instance, with the final Message and List of InnerExceptions.</param> /// <param name="error">Not null</param> /// <param name="message">If null or whitespace, will be set to the <c>error</c>'s Message.</param> /// <returns>The result from your constructor..</returns> /// <exception cref="ArgumentNullException"></exception> public static TAggregateException AggregateError <TAggregateException>( this TAggregateException aggregateException, Func <string, IEnumerable <Exception>, TAggregateException> constructor, Exception error, string message = null) where TAggregateException : AggregateException { if (constructor == null) { throw new ArgumentNullException(nameof(constructor)); } if (error == null) { throw new ArgumentNullException(nameof(error)); } if (string.IsNullOrWhiteSpace(message)) { message = error.Message; } return(constructor( message, error.AsSingle() .Concat( aggregateException?.InnerExceptions ?? EnumerableHelper.EmptyEnumerable <Exception>()))); }