ArgumentCannotBeOfTypeVoid() static private method

ArgumentException with message like "Argument type cannot be System.Void."
static private ArgumentCannotBeOfTypeVoid ( string paramName ) : Exception
paramName string
return System.Exception
Esempio n. 1
0
        private static void Validate(Type type, bool allowByRef)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            TypeUtils.ValidateType(type, nameof(type), allowByRef, allowPointer: false);

            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }
        }
Esempio n. 2
0
        private static void Validate(Type type, bool allowByRef)
        {
            ArgumentNullException.ThrowIfNull(type);
            TypeUtils.ValidateType(type, nameof(type), allowByRef, allowPointer: false);

            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Creates a <see cref="NewArrayExpression"/> of the specified type from the provided initializers.
        /// </summary>
        /// <param name="type">A Type that represents the element type of the array.</param>
        /// <param name="initializers">The expressions used to create the array elements.</param>
        /// <returns>A <see cref="NewArrayExpression"/> that has the <see cref="NodeType"/> property equal to <see cref="ExpressionType.NewArrayInit"/> and the <see cref="NewArrayExpression.Expressions"/> property set to the specified value.</returns>
        public static NewArrayExpression NewArrayInit(Type type, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            ContractUtils.RequiresNotNull(initializers, nameof(initializers));
            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }

            TypeUtils.ValidateType(type, nameof(type));
            if (type.IsByRef)
            {
                throw Error.TypeMustNotBeByRef(nameof(type));
            }

            if (type.IsPointer)
            {
                throw Error.TypeMustNotBePointer(nameof(type));
            }

            ReadOnlyCollection <Expression> initializerList = initializers.ToReadOnly();

            Expression[] newList = null;
            for (int i = 0, n = initializerList.Count; i < n; i++)
            {
                Expression expr = initializerList[i];
                RequiresCanRead(expr, nameof(initializers), i);

                if (!TypeUtils.AreReferenceAssignable(type, expr.Type))
                {
                    if (!TryQuote(type, ref expr))
                    {
                        throw Error.ExpressionTypeCannotInitializeArrayType(expr.Type, type);
                    }
                    if (newList == null)
                    {
                        newList = new Expression[initializerList.Count];
                        for (int j = 0; j < i; j++)
                        {
                            newList[j] = initializerList[j];
                        }
                    }
                }
                if (newList != null)
                {
                    newList[i] = expr;
                }
            }
            if (newList != null)
            {
                initializerList = new TrueReadOnlyCollection <Expression>(newList);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayInit, type.MakeArrayType(), initializerList));
        }
Esempio n. 4
0
        /// <summary>
        /// Creates a <see cref="NewArrayExpression"/> that represents creating an array that has a specified rank.
        /// </summary>
        /// <param name="type">A <see cref="System.Type"/> that represents the element type of the array.</param>
        /// <param name="bounds">An <see cref="IEnumerable{T}"/> that contains <see cref="Expression"/> objects to use to populate the <see cref="NewArrayExpression.Expressions"/> collection.</param>
        /// <returns>A <see cref="NewArrayExpression"/> that has the <see cref="NodeType"/> property equal to <see cref="ExpressionType.NewArrayBounds"/> and the <see cref="NewArrayExpression.Expressions"/> property set to the specified value.</returns>
        public static NewArrayExpression NewArrayBounds(Type type, IEnumerable <Expression> bounds)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            ContractUtils.RequiresNotNull(bounds, nameof(bounds));

            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }

            TypeUtils.ValidateType(type, nameof(type));
            if (type.IsByRef)
            {
                throw Error.TypeMustNotBeByRef(nameof(type));
            }

            if (type.IsPointer)
            {
                throw Error.TypeMustNotBePointer(nameof(type));
            }

            ReadOnlyCollection <Expression> boundsList = bounds.ToReadOnly();

            int dimensions = boundsList.Count;

            if (dimensions <= 0)
            {
                throw Error.BoundsCannotBeLessThanOne(nameof(bounds));
            }

            for (int i = 0; i < dimensions; i++)
            {
                Expression expr = boundsList[i];
                RequiresCanRead(expr, nameof(bounds), i);
                if (!TypeUtils.IsInteger(expr.Type))
                {
                    throw Error.ArgumentMustBeInteger(nameof(bounds), i);
                }
            }

            Type arrayType;

            if (dimensions == 1)
            {
                //To get a vector, need call Type.MakeArrayType().
                //Type.MakeArrayType(1) gives a non-vector array, which will cause type check error.
                arrayType = type.MakeArrayType();
            }
            else
            {
                arrayType = type.MakeArrayType(dimensions);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayBounds, arrayType, bounds.ToReadOnly()));
        }
Esempio n. 5
0
 /// <summary>
 /// Creates a <see cref="ParameterExpression" /> node that can be used to identify a parameter or a variable in an expression tree.
 /// </summary>
 /// <param name="type">The type of the parameter or variable.</param>
 /// <param name="name">The name of the parameter or variable, used for debugging or pretty printing purpose only.</param>
 /// <returns>A <see cref="ParameterExpression" /> node with the specified name and type.</returns>
 public static ParameterExpression Variable(Type type, string name)
 {
     ContractUtils.RequiresNotNull(type, "type");
     if (type == typeof(void))
     {
         throw Error.ArgumentCannotBeOfTypeVoid();
     }
     if (type.IsByRef)
     {
         throw Error.TypeMustNotBeByRef();
     }
     return(ParameterExpression.Make(type, name, false));
 }
Esempio n. 6
0
        private static void Validate(Type type)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            TypeUtils.ValidateType(type, nameof(type));

            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }

            if (type.IsPointer)
            {
                throw Error.TypeMustNotBePointer(nameof(type));
            }
        }
Esempio n. 7
0
        /// <summary>
        /// Creates a new array expression of the specified type from the provided initializers.
        /// </summary>
        /// <param name="type">A Type that represents the element type of the array.</param>
        /// <param name="initializers">The expressions used to create the array elements.</param>
        public static NewArrayExpression NewArrayInit(Type type, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, "type");
            ContractUtils.RequiresNotNull(initializers, "initializers");
            if (type.Equals(typeof(void)))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }

            ReadOnlyCollection <Expression> initializerList = initializers.ToReadOnly();

            Expression[] newList = null;
            for (int i = 0, n = initializerList.Count; i < n; i++)
            {
                Expression expr = initializerList[i];
                RequiresCanRead(expr, "initializers");

                if (!TypeUtils.AreReferenceAssignable(type, expr.Type))
                {
                    if (TypeUtils.IsSameOrSubclass(typeof(Expression), type) && type.IsAssignableFrom(expr.GetType()))
                    {
                        expr = Expression.Quote(expr);
                    }
                    else
                    {
                        throw Error.ExpressionTypeCannotInitializeArrayType(expr.Type, type);
                    }
                    if (newList == null)
                    {
                        newList = new Expression[initializerList.Count];
                        for (int j = 0; j < i; j++)
                        {
                            newList[j] = initializerList[j];
                        }
                    }
                }
                if (newList != null)
                {
                    newList[i] = expr;
                }
            }
            if (newList != null)
            {
                initializerList = new ReadOnlyCollection <Expression>(newList);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayInit, type.MakeArrayType(), initializerList));
        }
Esempio n. 8
0
        /// <summary>
        /// Creates a new array expression of the specified type from the provided initializers.
        /// </summary>
        /// <param name="type">A Type that represents the element type of the array.</param>
        /// <param name="initializers">The expressions used to create the array elements.</param>
        /// <returns>An instance of the <see cref="NewArrayExpression"/>.</returns>
        public static NewArrayExpression NewArrayInit(Type type, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, "type");
            ContractUtils.RequiresNotNull(initializers, "initializers");
            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }

            var initializerList = initializers.ToReadOnly();

            Expression[] newList = null;
            var          n       = initializerList.Count;

            for (var i = 0; i < n; i++)
            {
                var expr = initializerList[i];
                RequiresCanRead(expr, "initializers");

                if (!TypeHelper.AreReferenceAssignable(type, expr.Type))
                {
                    if (!TryQuote(type, ref expr))
                    {
                        throw Error.ExpressionTypeCannotInitializeArrayType(expr.Type, type);
                    }
                    if (newList == null)
                    {
                        newList = new Expression[n];
                        for (var j = 0; j < i; j++)
                        {
                            newList[j] = initializerList[j];
                        }
                    }
                }
                if (newList != null)
                {
                    newList[i] = expr;
                }
            }
            if (newList != null)
            {
                initializerList = new TrueReadOnlyCollection <Expression>(newList);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayInit, type.MakeArrayType(), initializerList));
        }
Esempio n. 9
0
        /// <summary>
        /// Creates a <see cref="ParameterExpression" /> node that can be used to identify a parameter or a variable in an expression tree.
        /// </summary>
        /// <param name="type">The type of the parameter or variable.</param>
        /// <param name="name">The name of the parameter or variable, used for debugging or pretty printing purpose only.</param>
        /// <returns>A <see cref="ParameterExpression" /> node with the specified name and type.</returns>
        public static ParameterExpression Parameter(Type type, string name)
        {
            ContractUtils.RequiresNotNull(type, "type");

            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }

            bool byref = type.IsByRef;

            if (byref)
            {
                type = type.GetElementType();
            }

            return(ParameterExpression.Make(type, name, byref));
        }
Esempio n. 10
0
 /// <summary>
 /// Creates a <see cref="NewExpression"/> that represents calling the parameterless constructor of the specified type.
 /// </summary>
 /// <param name="type">A <see cref="Type"/> that has a constructor that takes no arguments. </param>
 /// <returns>A <see cref="NewExpression"/> that has the <see cref="NodeType"/> property equal to New and the Constructor property set to the ConstructorInfo that represents the parameterless constructor of the specified type.</returns>
 public static NewExpression New(Type type)
 {
     ContractUtils.RequiresNotNull(type, "type");
     if (type == typeof(void))
     {
         throw Error.ArgumentCannotBeOfTypeVoid();
     }
     if (!type.IsValueType)
     {
         var constructorInfo = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).SingleOrDefault(c => c.GetParameters().Length == 0);
         if (constructorInfo == null)
         {
             throw Error.TypeMissingDefaultConstructor(type);
         }
         return(New(constructorInfo));
     }
     return(new NewValueTypeExpression(type, EmptyCollection <Expression> .Instance, null));
 }
Esempio n. 11
0
        /// <summary>
        /// Creates a <see cref="NewArrayExpression"/> that represents creating an array that has a specified rank.
        /// </summary>
        /// <param name="type">A <see cref="Type"/> that represents the element type of the array.</param>
        /// <param name="bounds">An IEnumerable{T} that contains Expression objects to use to populate the Expressions collection.</param>
        /// <returns>A <see cref="NewArrayExpression"/> that has the <see cref="P:NodeType"/> property equal to type and the <see cref="P:Expressions"/> property set to the specified value.</returns>
        public static NewArrayExpression NewArrayBounds(Type type, IEnumerable <Expression> bounds)
        {
            ContractUtils.RequiresNotNull(type, "type");
            ContractUtils.RequiresNotNull(bounds, "bounds");

            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }

            var boundsList = bounds.ToReadOnly();

            var dimensions = boundsList.Count;

            if (dimensions <= 0)
            {
                throw Error.BoundsCannotBeLessThanOne();
            }

            for (var i = 0; i < dimensions; i++)
            {
                var expr = boundsList[i];
                RequiresCanRead(expr, "bounds");
                if (!expr.Type.IsInteger())
                {
                    throw Error.ArgumentMustBeInteger();
                }
            }

            Type arrayType;

            if (dimensions == 1)
            {
                //To get a vector, need call Type.MakeArrayType().
                //Type.MakeArrayType(1) gives a non-vector array, which will cause type check error.
                arrayType = type.MakeArrayType();
            }
            else
            {
                arrayType = type.MakeArrayType(dimensions);
            }

            return(NewArrayExpression.Make(ExpressionType.NewArrayBounds, arrayType, boundsList));
        }
Esempio n. 12
0
        //CONFORMING
        public static NewExpression New(Type type)
        {
            ContractUtils.RequiresNotNull(type, "type");
            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }
            ConstructorInfo ci = null;

            if (!type.IsValueType)
            {
                ci = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, null, System.Type.EmptyTypes, null);
                if (ci == null)
                {
                    throw Error.TypeMissingDefaultConstructor(type);
                }
                return(New(ci));
            }
            return(new NewValueTypeExpression(type, EmptyReadOnlyCollection <Expression> .Instance, null));
        }
Esempio n. 13
0
        /// <summary>
        /// Creates a <see cref="NewExpression"/> that represents calling the parameterless constructor of the specified type.
        /// </summary>
        /// <param name="type">A <see cref="Type"/> that has a constructor that takes no arguments. </param>
        /// <returns>A <see cref="NewExpression"/> that has the <see cref="NodeType"/> property equal to New and the Constructor property set to the ConstructorInfo that represents the parameterless constructor of the specified type.</returns>
        public static NewExpression New(Type type)
        {
            ContractUtils.RequiresNotNull(type, "type");
            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }
            ConstructorInfo ci = null;

            if (!type.GetTypeInfo().IsValueType)
            {
                ci = type.GetConstructor(Array.Empty <Type>());
                if (ci == null)
                {
                    throw Error.TypeMissingDefaultConstructor(type);
                }
                return(New(ci));
            }
            return(new NewValueTypeExpression(type, EmptyReadOnlyCollection <Expression> .Instance, null));
        }
Esempio n. 14
0
        /// <summary>
        /// Creates a <see cref="NewExpression"/> that represents calling the parameterless constructor of the specified type.
        /// </summary>
        /// <param name="type">A <see cref="Type"/> that has a constructor that takes no arguments.</param>
        /// <returns>A <see cref="NewExpression"/> that has the <see cref="NodeType"/> property equal to <see cref="ExpressionType.New"/> and the <see cref="NewExpression.Constructor"/> property set to the <see cref="ConstructorInfo"/> that represents the parameterless constructor of the specified type.</returns>
        public static NewExpression New(Type type)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }
            TypeUtils.ValidateType(type, nameof(type));

            if (!type.GetTypeInfo().IsValueType)
            {
                ConstructorInfo ci = type.GetConstructors(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic).SingleOrDefault(c => c.GetParametersCached().Length == 0);
                if (ci == null)
                {
                    throw Error.TypeMissingDefaultConstructor(type, nameof(type));
                }
                return(New(ci));
            }
            return(new NewValueTypeExpression(type, EmptyReadOnlyCollection <Expression> .Instance, null));
        }
Esempio n. 15
0
        /// <summary>
        /// Creates a <see cref="ParameterExpression"/> node that can be used to identify a parameter or a variable in an expression tree.
        /// </summary>
        /// <param name="type">The type of the parameter or variable.</param>
        /// <param name="name">The name of the parameter or variable, used for debugging or pretty printing purpose only.</param>
        /// <returns>A <see cref="ParameterExpression"/> node with the specified name and type.</returns>
        public static ParameterExpression Variable(Type type, string name)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            TypeUtils.ValidateType(type, nameof(type));
            if (type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid(nameof(type));
            }
            if (type.IsByRef)
            {
                throw Error.TypeMustNotBeByRef(nameof(type));
            }

            if (type.IsPointer)
            {
                throw Error.TypeMustNotBePointer(nameof(type));
            }

            return(ParameterExpression.Make(type, name, isByRef: false));
        }
        public static SwitchCSharpStatement Switch(Expression switchValue, LabelTarget breakLabel, IEnumerable <ParameterExpression> variables, IEnumerable <CSharpSwitchCase> cases)
        {
            RequiresCanRead(switchValue, nameof(switchValue));
            RequiresNotNull(breakLabel, nameof(breakLabel));

            if (switchValue.Type == typeof(void))
            {
                throw LinqError.ArgumentCannotBeOfTypeVoid();
            }

            if (breakLabel.Type != typeof(void))
            {
                throw Error.SwitchBreakLabelShouldBeVoid();
            }

            var type = switchValue.Type;

            CheckValidSwitchType(type);

            var isNullable  = type == typeof(string) || type.IsNullableType();
            var nonNullType = type.GetNonNullableType();

            // NB: Switch in C# can be empty, so less checks than LINQ here. Also no custom comparison method.

            var casesList = cases.ToReadOnly();

            if (casesList.Count > 0)
            {
                var testValues = new HashSet <object>();

                foreach (var @case in casesList)
                {
                    RequiresNotNull(@case, nameof(cases));

                    foreach (var value in @case.TestValues)
                    {
                        if (!testValues.Add(value))
                        {
                            throw Error.DuplicateTestValue(value.ToDebugString());
                        }

                        if (value == null)
                        {
                            if (!isNullable)
                            {
                                throw Error.SwitchCantHaveNullCase(type);
                            }
                        }
                        else if (value != SwitchCaseDefaultValue)
                        {
                            var valueType = value.GetType().GetNonNullableType();

                            if (valueType != nonNullType)
                            {
                                throw Error.SwitchCaseHasIncompatibleType(value.GetType(), type);
                            }
                        }
                    }
                }
            }

            var variableList = CheckUniqueVariables(variables, nameof(variables));

            return(new SwitchCSharpStatement(switchValue, breakLabel, variableList, casesList));
        }
Esempio n. 17
0
        /// <summary>
        /// Creates a <see cref="SwitchExpression"/>.
        /// </summary>
        /// <param name="type">The result type of the switch.</param>
        /// <param name="switchValue">The value to be tested against each case.</param>
        /// <param name="defaultBody">The result of the switch if no cases are matched.</param>
        /// <param name="comparison">The equality comparison method to use.</param>
        /// <param name="cases">The valid cases for this switch.</param>
        /// <returns>The created <see cref="SwitchExpression"/>.</returns>
        public static SwitchExpression Switch(Type type, Expression switchValue, Expression defaultBody, MethodInfo comparison, IEnumerable <SwitchCase> cases)
        {
            RequiresCanRead(switchValue, nameof(switchValue));
            if (switchValue.Type == typeof(void))
            {
                throw Error.ArgumentCannotBeOfTypeVoid();
            }

            var caseList = cases.ToReadOnly();

            ContractUtils.RequiresNotNullItems(caseList, nameof(cases));

            // Type of the result. Either provided, or it is type of the branches.
            Type resultType;

            if (type != null)
            {
                resultType = type;
            }
            else if (caseList.Count != 0)
            {
                resultType = caseList[0].Body.Type;
            }
            else if (defaultBody != null)
            {
                resultType = defaultBody.Type;
            }
            else
            {
                resultType = typeof(void);
            }
            bool customType = type != null;

            if (comparison != null)
            {
                var pms = comparison.GetParametersCached();
                if (pms.Length != 2)
                {
                    throw Error.IncorrectNumberOfMethodCallArguments(comparison);
                }
                // Validate that the switch value's type matches the comparison method's
                // left hand side parameter type.
                var  leftParam  = pms[0];
                bool liftedCall = false;
                if (!ParameterIsAssignable(leftParam, switchValue.Type))
                {
                    liftedCall = ParameterIsAssignable(leftParam, switchValue.Type.GetNonNullableType());
                    if (!liftedCall)
                    {
                        throw Error.SwitchValueTypeDoesNotMatchComparisonMethodParameter(switchValue.Type, leftParam.ParameterType);
                    }
                }

                var rightParam = pms[1];
                foreach (var c in caseList)
                {
                    ContractUtils.RequiresNotNull(c, nameof(cases));
                    ValidateSwitchCaseType(c.Body, customType, resultType, nameof(cases));
                    for (int i = 0; i < c.TestValues.Count; i++)
                    {
                        // When a comparison method is provided, test values can have different type but have to
                        // be reference assignable to the right hand side parameter of the method.
                        Type rightOperandType = c.TestValues[i].Type;
                        if (liftedCall)
                        {
                            if (!rightOperandType.IsNullableType())
                            {
                                throw Error.TestValueTypeDoesNotMatchComparisonMethodParameter(rightOperandType, rightParam.ParameterType);
                            }
                            rightOperandType = rightOperandType.GetNonNullableType();
                        }
                        if (!ParameterIsAssignable(rightParam, rightOperandType))
                        {
                            throw Error.TestValueTypeDoesNotMatchComparisonMethodParameter(rightOperandType, rightParam.ParameterType);
                        }
                    }
                }
            }
            else if (caseList.Count != 0)
            {
                // When comparison method is not present, all the test values must have
                // the same type. Use the first test value's type as the baseline.
                var firstTestValue = caseList[0].TestValues[0];
                foreach (var c in caseList)
                {
                    ContractUtils.RequiresNotNull(c, nameof(cases));
                    ValidateSwitchCaseType(c.Body, customType, resultType, nameof(cases));
                    // When no comparison method is provided, require all test values to have the same type.
                    for (int i = 0; i < c.TestValues.Count; i++)
                    {
                        if (!TypeUtils.AreEquivalent(firstTestValue.Type, c.TestValues[i].Type))
                        {
                            throw new ArgumentException(Strings.AllTestValuesMustHaveSameType, nameof(cases));
                        }
                    }
                }

                // Now we need to validate that switchValue.Type and testValueType
                // make sense in an Equal node. Fortunately, Equal throws a
                // reasonable error, so just call it.
                var equal = Equal(switchValue, firstTestValue, false, comparison);

                // Get the comparison function from equals node.
                comparison = equal.Method;
            }

            if (defaultBody == null)
            {
                if (resultType != typeof(void))
                {
                    throw Error.DefaultBodyMustBeSupplied();
                }
            }
            else
            {
                ValidateSwitchCaseType(defaultBody, customType, resultType, nameof(defaultBody));
            }

            // if we have a non-boolean user-defined equals, we don't want it.
            if (comparison != null && comparison.ReturnType != typeof(bool))
            {
                throw Error.EqualityMustReturnBoolean(comparison);
            }

            return(new SwitchExpression(resultType, switchValue, defaultBody, comparison, caseList));
        }
        public static NewMultidimensionalArrayInitCSharpExpression NewMultidimensionalArrayInit(Type type, IEnumerable <int> bounds, IEnumerable <Expression> initializers)
        {
            ContractUtils.RequiresNotNull(type, nameof(type));
            ContractUtils.RequiresNotNull(bounds, nameof(bounds));
            ContractUtils.RequiresNotNull(initializers, nameof(initializers));

            if (type.Equals(typeof(void)))
            {
                throw LinqError.ArgumentCannotBeOfTypeVoid();
            }

            var boundsList = bounds.ToReadOnly();

            int dimensions = boundsList.Count;

            if (dimensions <= 0)
            {
                throw LinqError.BoundsCannotBeLessThanOne();
            }

            var length = 1;

            foreach (var bound in boundsList)
            {
                if (bound < 0)
                {
                    throw Error.BoundCannotBeLessThanZero();
                }

                checked
                {
                    length *= bound;
                }
            }

            var initializerList = initializers.ToReadOnly();

            if (initializerList.Count != length)
            {
                throw Error.ArrayBoundsElementCountMismatch();
            }

            var newList = default(Expression[]);

            for (int i = 0, n = initializerList.Count; i < n; i++)
            {
                var expr = initializerList[i];
                RequiresCanRead(expr, nameof(initializers));

                if (!TypeUtils.AreReferenceAssignable(type, expr.Type))
                {
                    if (!TryQuote(type, ref expr))
                    {
                        throw LinqError.ExpressionTypeCannotInitializeArrayType(expr.Type, type);
                    }

                    if (newList == null)
                    {
                        newList = new Expression[initializerList.Count];
                        for (int j = 0; j < i; j++)
                        {
                            newList[j] = initializerList[j];
                        }
                    }
                }

                if (newList != null)
                {
                    newList[i] = expr;
                }
            }

            if (newList != null)
            {
                initializerList = new TrueReadOnlyCollection <Expression>(newList);
            }

            return(new NewMultidimensionalArrayInitCSharpExpression(type.MakeArrayType(boundsList.Count), boundsList, initializerList));
        }