/// <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)); }