public static Expression ForEach(ParameterExpression item, Expression source, Expression body)
        {
            if (!typeof(IEnumerable).IsAssignableFrom(source.Type))
            {
                throw new InvalidOperationException($"{source.Type} does not implement IEnumerable and cannot be iterated using foreach");
            }

            ParameterExpression enumerator = Expression.Parameter(typeof(IEnumerator), "enumerator");
            LabelTarget         forEachEnd = Expression.Label();

            return(Expression.Block(
                       new[] { item, enumerator },

                       Expression.Assign(
                           enumerator,
                           Expression.Call(source, EnumerableMembers.GetEnumerator())
                           ),

                       Expression.Loop(
                           Expression.IfThenElse(
                               Expression.Call(enumerator, EnumerableMembers.MoveNext()),

                               Expression.Block(
                                   Expression.Assign(item, Expression.Convert(Expression.Property(enumerator, EnumerableMembers.Current()), item.Type)),
                                   body
                                   ),

                               Expression.Break(forEachEnd)
                               ),
                           forEachEnd
                           )
                       ));
        }
示例#2
0
 private Expression MoveEnumerator(ParameterExpression enumerator, ParameterExpression someLeft)
 {
     return(Expression.Assign(
                someLeft,
                Expression.Call(
                    enumerator,
                    EnumerableMembers.MoveNext(typeof(IDiffItem))
                    )
                ));
 }