ForEachExpression

Mar 3, 2009 at 2:43 PM
Are there any plans for the ForEachExpression?
Any workaround?

Thanks

Coordinator
Mar 3, 2009 at 5:17 PM

It would be something like:

Block (enum_var, item_var) [

            Assign (enum_var, Call(enumerable_obj_expr, GetEnum))

Loop (break_target) [

Conditional ( Call (enum_var, Next),

                        Assign (item_var, Property(enum_var, Current)),

                        Goto (break_target) )

foreach_body

]

]

Bill

From: spyrop [mailto:notifications@codeplex.com]
Sent: Tuesday, March 03, 2009 7:44 AM
To: Bill Chiles
Subject: ForEachExpression [dlr:49062]

From: spyrop

Are there any plans for the ForEachExpression?
Any workaround?

Thanks

Read the full discussion online.

To add a post to this discussion, reply to this email (dlr@discussions.codeplex.com)

To start a new discussion for this project, email dlr@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe or change your settings on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com

Mar 3, 2009 at 5:30 PM
The "foreach" language construct is pretty high-level and has semantics that are very specific to the language you're using.  In fact, the C# and VB.NET compilers can emit a variety of very different code depending on the language and the type of object you are iterating over.  Such a node would be out of place in the DLR, whose expression trees are intended to be low-level building blocks.

Here's a snippet of code that shows iterating over an IEnumerable represented by the "enumerable" var.  ("body" is some other ET that makes use of "variable").  Is there some other example you'd like to see?

            ParameterExpression temp = Expression.Variable(typeof(IEnumerator), "$enumerator");
            ParameterExpression variable = Expression.Variable(typeof(object), "value");
            return Expression.Block(
                new[] { temp, variable },
                Expression.Assign(temp, Expression.Call(enumerable, typeof(IEnumerable).GetMethod("GetEnumerator"))),
                TreeUtils.Loop(
                    Expression.Call(temp, typeof(IEnumerator).GetMethod("MoveNext")),
                    null,
                    Expression.Block(
                        Expression.Assign(
                            variable,
                            Expression.Convert(
                                Expression.Property(temp, typeof(IEnumerator).GetProperty("Current")),
                                variable.Type
                            )
                        ),
                        body
                    ),
                    null,
                    null,
                    null
                )
            );
Mar 3, 2009 at 9:30 PM

By the way, TreeUtils.Loop is from Microsoft.Scripting.dll and looks like this:

        public static LoopExpression Loop(Expression test, Expression increment, Expression body, Expression @else, LabelTarget @break, LabelTarget @continue) {
            if (test != null) {
                if (@break == null) {
                    @break = Expression.Label();
                }
            }

            return Expression.Loop(
                Expression.Block(
                    test != null
                        ? (Expression)Expression.Condition(
                            test,
                            Utils.Empty(),
                            Expression.Block(
                                @else != null ? @else : Utils.Empty(),
                                Expression.Break(@break)
                            )
                        )
                        : Utils.Empty(),
                    body,
                    @continue != null ? (Expression)Expression.Label(@continue) : Utils.Empty(),
                    increment != null ? increment : Utils.Empty()
                ),
                @break,
                null
            );