internal ForEachCSharpStatement(EnumeratorInfo enumeratorInfo, ReadOnlyCollection <ParameterExpression> variables, Expression collection, Expression body, LabelTarget breakLabel, LabelTarget continueLabel) : base(body, breakLabel, continueLabel) { EnumeratorInfo = enumeratorInfo; Variables = variables; Collection = collection; }
/// <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="enumeratorInfo">The <see cref="EnumeratorInfo" /> property of the result.</param> /// <param name="breakLabel">The <see cref="LoopCSharpStatement.BreakLabel" /> property of the result.</param> /// <param name="continueLabel">The <see cref="LoopCSharpStatement.ContinueLabel" /> property of the result.</param> /// <param name="variables">The <see cref="Variables" /> property of the result.</param> /// <param name="collection">The <see cref="Collection" /> property of the result.</param> /// <param name="conversion">The <see cref="Conversion"/> property of the result.</param> /// <param name="body">The <see cref="LoopCSharpStatement.Body" /> property of the result.</param> /// <param name="deconstruction">The <see cref="Deconstruction"/> property of the result.</param> /// <param name="awaitInfo">The <see cref="AwaitInfo"/> property of the result.</param> /// <returns>This expression if no children changed, or an expression with the updated children.</returns> public ForEachCSharpStatement Update(EnumeratorInfo enumeratorInfo, LabelTarget breakLabel, LabelTarget continueLabel, IEnumerable <ParameterExpression> variables, Expression collection, LambdaExpression conversion, Expression body, LambdaExpression deconstruction, AwaitInfo awaitInfo) { if (enumeratorInfo == EnumeratorInfo && breakLabel == BreakLabel && continueLabel == ContinueLabel && SameElements(ref variables, Variables) && collection == Collection && conversion == Conversion && body == Body && deconstruction == Deconstruction && awaitInfo == AwaitInfo) { return(this); } return(CSharpExpression.ForEach(awaitInfo, variables, collection, body, breakLabel, continueLabel, conversion, deconstruction)); }
internal static ForEachCSharpStatement Make(EnumeratorInfo enumeratorInfo, AwaitInfo awaitInfo, ReadOnlyCollection <ParameterExpression> variables, Expression collection, Expression body, LabelTarget breakLabel, LabelTarget continueLabel, LambdaExpression conversion, LambdaExpression deconstruction) { if (variables.Count == 0) { throw Error.ForEachNeedsOneOrMoreVariables(); } RequiresNotNullItems(variables, nameof(variables)); if (!AreReferenceAssignable(enumeratorInfo.CollectionType, collection.Type)) { throw Error.ForEachCollectionTypeNotCompatibleWithCollectionExpression(enumeratorInfo.CollectionType, collection.Type); } RequiresCanRead(body, nameof(body)); ValidateLoop(body, breakLabel, continueLabel); var firstVariable = variables[0]; var firstVariableType = firstVariable.Type; if (variables.Count == 1) { if (deconstruction != null) { throw Error.ForEachDeconstructionNotSupportedWithOneVariable(); } ValidateConversion(firstVariableType, enumeratorInfo.ElementType, ref conversion); } else { if (deconstruction == null) { throw Error.ForEachDeconstructionRequiredForMultipleVariables(); } ValidateDeconstruction(enumeratorInfo.ElementType, ref conversion, deconstruction, variables); } if (awaitInfo == null) { if (collection.Type == typeof(string) && variables.Count == 1 && firstVariableType == typeof(char) && conversion == null && deconstruction == null) { return(new StringForEachStatement(enumeratorInfo, variables, collection, body, breakLabel, continueLabel)); } else if (collection.Type.IsArray) { if (collection.Type.IsVector()) { if (conversion == null && deconstruction == null) { return(new SimpleArrayForEachCSharpStatement(enumeratorInfo, variables, collection, body, breakLabel, continueLabel)); } else { return(new ArrayForEachCSharpStatement(enumeratorInfo, variables, collection, body, breakLabel, continueLabel, conversion, deconstruction)); } } else { return(new MultiDimensionalArrayForEachCSharpStatement(enumeratorInfo, variables, collection, body, breakLabel, continueLabel, conversion, deconstruction)); } } } else { awaitInfo.RequiresCanBind(enumeratorInfo.MoveNext.Body); } return(new BoundForEachCSharpStatement(enumeratorInfo, variables, collection, body, breakLabel, continueLabel, conversion, deconstruction, awaitInfo)); }