/// <summary> /// Creates a catch block. /// </summary> /// <param name="variables">The variables introduced by the catch block.</param> /// <param name="type">The type of the exceptions to handle.</param> /// <param name="variable">The variable to assign a caught exception to.</param> /// <param name="body">The body of the catch block.</param> /// <param name="filter">The filter to apply.</param> /// <returns>The created <see cref="CSharpCatchBlock"/>.</returns> public static CSharpCatchBlock MakeCatchBlock(IEnumerable <ParameterExpression> variables, Type type, ParameterExpression variable, Expression body, Expression filter) { var variablesList = CheckUniqueVariables(variables, nameof(variables)); Requires(variable == null || AreEquivalent(variable.Type, type), nameof(variable)); if (variable != null) { if (variable.IsByRef) { throw LinqError.VariableMustNotBeByRef(variable, variable.Type); } // REVIEW: See UsingCSharpStatement for a similar situation. if (!variablesList.Contains(variable)) { throw Error.CatchVariableNotInScope(variable); } if (type == null) { type = variable.Type; } else if (!AreEquivalent(type, variable.Type)) { throw Error.CatchTypeNotEquivalentWithVariableType(type, variable.Type); } } else if (type != null) { ValidateType(type); } else { type = typeof(object); // NB: Used to catch all. } RequiresCanRead(body, nameof(body)); if (filter != null) { RequiresCanRead(filter, nameof(filter)); if (filter.Type != typeof(bool)) { throw LinqError.ArgumentMustBeBoolean(); } } return(new CSharpCatchBlock(variablesList, type, variable, body, filter)); }