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 ) )); }
private Expression MoveEnumerator(ParameterExpression enumerator, ParameterExpression someLeft) { return(Expression.Assign( someLeft, Expression.Call( enumerator, EnumerableMembers.MoveNext(typeof(IDiffItem)) ) )); }