/// <summary>
/// Creates a <see cref="TryExpression"/> representing a try block with the specified elements.
/// </summary>
/// <param name="type">The result type of the try expression. If null, body and all handlers must have identical type.</param>
/// <param name="body">The body of the try block.</param>
/// <param name="finally">The body of the finally block. Pass null if the try block has no finally block associated with it.</param>
/// <param name="fault">The body of the t block. Pass null if the try block has no fault block associated with it.</param>
/// <param name="handlers">A collection of <see cref="CatchBlock"/>s representing the catch statements to be associated with the try block.</param>
/// <returns>The created <see cref="TryExpression"/>.</returns>
public static TryExpression MakeTry(Type type, Expression body, Expression @finally, Expression fault, IEnumerable <CatchBlock> handlers)
{
RequiresCanRead(body, nameof(body));
ReadOnlyCollection <CatchBlock> @catch = handlers.ToReadOnly();
ContractUtils.RequiresNotNullItems(@catch, nameof(handlers));
ValidateTryAndCatchHaveSameType(type, body, @catch);
if (fault != null)
{
if (@finally != null || @catch.Count > 0)
{
throw Error.FaultCannotHaveCatchOrFinally(nameof(fault));
}
RequiresCanRead(fault, nameof(fault));
}
else if (@finally != null)
{
RequiresCanRead(@finally, nameof(@finally));
}
else if (@catch.Count == 0)
{
throw Error.TryMustHaveCatchFinallyOrFault();
}
return(new TryExpression(type ?? body.Type, body, @finally, fault, @catch));
}