Example #1
0
        /// <summary>
        /// Creates a <see cref="ForEachCSharpStatement"/> that represents a foreach loop.
        /// </summary>
        /// <param name="variable">The iteration variable.</param>
        /// <param name="collection">The collection to iterate over.</param>
        /// <param name="body">The body of the loop.</param>
        /// <param name="break">The break target used by the loop body.</param>
        /// <param name="continue">The continue target used by the loop body.</param>
        /// <param name="conversion">The conversion function used to convert elements in the collection to the iteration variable type.</param>
        /// <returns>The created <see cref="ForEachCSharpStatement"/>.</returns>
        public static ForEachCSharpStatement ForEach(ParameterExpression variable, Expression collection, Expression body, LabelTarget @break, LabelTarget @continue, LambdaExpression conversion)
        {
            // NB: This is the overload the C# compiler can bind to. Note, however, that a bound foreach node in Roslyn has
            //     information about GetEnumerator, MoveNext, Current, etc. as well. We can infer the same information at
            //     runtime, but could also add an overload that has all of these.
            // NB: Conversion of the collection should be inserted as a Convert node by the compiler.
            //
            // TODO: Do we need to add a means to perform an enumerator conversion? Cf. ForEachEnumeratorInfo in Roslyn.

            return(ForEachCSharpStatement.Make(variable, collection, body, @break, @continue, conversion));
        }