/// <summary>
/// Creates a <see cref="BlockExpression"/> that contains the given variables and expressions.
/// </summary>
/// <param name="type">The result type of the block.</param>
/// <param name="variables">The variables in the block.</param>
/// <param name="expressions">The expressions in the block.</param>
/// <returns>The created <see cref="BlockExpression"/>.</returns>
public static BlockExpression Block(Type type, IEnumerable <ParameterExpression> variables, IEnumerable <Expression> expressions)
{
ContractUtils.RequiresNotNull(type, "type");
ContractUtils.RequiresNotNull(expressions, "expressions");
var expressionList = expressions.ToReadOnly();
var variableList = variables.ToReadOnly();
ContractUtils.RequiresNotEmpty(expressionList, "expressions");
RequiresCanRead(expressionList, "expressions");
ValidateVariables(variableList, "variables");
var last = expressionList.Last();
if (type != typeof(void))
{
if (!TypeHelper.AreReferenceAssignable(type, last.Type))
{
throw Error.ArgumentTypesMustMatch();
}
}
if (type != last.Type)
{
return(new ScopeWithType(variableList, expressionList, type));
}
if (expressionList.Count == 1)
{
return(new Scope1(variableList, expressionList[0]));
}
return(new ScopeN(variableList, expressionList));
}