/// <summary>
        /// Creates a list pattern.
        /// </summary>
        /// <param name="collectionType">The type of the collection.</param>
        /// <param name="variable">The variable to assign to.</param>
        /// <param name="patterns">The list of <see cref="CSharpPattern"/> patterns to apply to the elements of the collection, optionally containing a slice pattern.</param>
        /// <returns>A <see cref="ListCSharpPattern" /> representing a list pattern.</returns>
        public static ListCSharpPattern List(Type collectionType, ParameterExpression variable, IEnumerable <CSharpPattern> patterns)
        {
            collectionType ??= variable?.Type;
            var inputType = collectionType;

            if (inputType != null && inputType.IsValueType && !inputType.IsNullableType())
            {
                // NB: The pattern implies a null check so we "widen" the target type to nullable.
                inputType = typeof(Nullable <>).MakeGenericType(inputType);
            }

            var info = ObjectPatternInfo(PatternInfo(inputType, collectionType), variable);

            ValidateType(collectionType);

            Expression lengthAccess, indexerAccess;

            var input = Expression.Parameter(collectionType, "o");
            var index = Expression.Parameter(typeof(Index), "i");

            if (Helpers.IsVector(collectionType))
            {
                indexerAccess = CSharpExpression.ArrayAccess(input, index);
                lengthAccess  = Expression.ArrayLength(input);
            }
            else
            {
                var expr = CSharpExpression.IndexerAccess(input, index);

                indexerAccess = expr;
                lengthAccess  = Expression.MakeMemberAccess(input, expr.LengthOrCount);
            }

            return(List(info, Expression.Lambda(lengthAccess, input), Expression.Lambda(indexerAccess, input, index), patterns));
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="array">The <see cref="Array" /> property of the result.</param>
        /// <param name="indexes">The <see cref="Indexes" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public ArrayAccessCSharpExpression Update(Expression array, IEnumerable <Expression> indexes)
        {
            if (array == Array && SameElements(ref indexes, Indexes))
            {
                return(this);
            }

            return(CSharpExpression.ArrayAccess(array, indexes));
        }
        /// <summary>
        /// Creates a new expression that is like this one, but using the supplied children. If all of the children are the same, it will return this expression.
        /// </summary>
        /// <param name="array">The <see cref="Array" /> property of the result.</param>
        /// <param name="indexes">The <see cref="Indexes" /> property of the result.</param>
        /// <returns>This expression if no children changed, or an expression with the updated children.</returns>
        public ArrayAccessCSharpExpression Update(Expression array, IEnumerable <Expression> indexes)
        {
            if (array == Array && indexes == Indexes)
            {
                return(this);
            }

            return(CSharpExpression.ArrayAccess(array, indexes));
        }