Non-Generic ForEach

This topic applies to Windows Workflow Foundation 4 (WF4).

.NET Framework version 4 ships in its toolbox a set of Control Flow activities, including ForEach, which allows iterating through IEnumerable collections.

ForEach requires its Values property to be of type IEnumerable. This precludes users from iterating over data structures that implement IEnumerable interface (for example, ArrayList). The non-generic version of ForEach overcomes this requirement, at the expense of more run-time complexity for ensuring the compatibility of the types of the values in the collection.

This sample shows how to implement a non-generic ForEach activity and its designer. This activity can be used to iterate through ArrayList.

ForEach Activity

The C#/VB foreach statement enumerates the elements of a collection, executing an embedded statement for each element of the collection. The WF equivalent activities of foreach are ForEach and ParallelForEach. The ForEach activity contains a list of values and a body. At runtime, the list is iterated and the body is executed for each value in the list.

For most cases, the generic version of the activity should be the preferred solution, because it covers most of the scenarios in which it would be used, and provides type checking at compile time. The non-generic version can be used for iterating through types that implement the non-generic IEnumerable interface.

Class Definition

The following code example shows the definition of a non-generic ForEach activity.

[ContentProperty("Body")]
public class ForEach : NativeActivity
{
    [RequiredArgument]
    [DefaultValue(null)]
    InArgument<IEnumerable> Values { get; set; }

    [DefaultValue(null)]
    [DependsOn("Values")]
    ActivityAction<object> Body { get; set; } 
}
  • Body (optional)
    The ActivityAction of type Object, which is executed for each element in the collection. Each individual element is passed into the Body through its Argument property.
  • Values (optional)
    The collection of elements that are iterated over. Ensuring that all elements of the collection are of compatible types is done at run-time.

Example of Using ForEach

The following code demonstrates how to use the ForEach activity in an application.

string[] names = { "bill", "steve", "ray" };

DelegateInArgument<object> iterationVariable = new DelegateInArgument<object>() { Name = "iterationVariable" };

Activity sampleUsage =
    new ForEach
    {
       Values = new InArgument<IEnumerable>(c=> names),
       Body = new ActivityAction<object> 
       {                        
           Argument = iterationVariable,
           Handler = new WriteLine
           {
               Text = new InArgument<string>(env => string.Format("Hello {0}",                                                               iterationVariable.Get(env)))
           }
       }
   };

Condition Message Severity Exception Type

Values is null

Value for a required activity argument 'Values' was not supplied.

Error

InvalidOperationException

ForEach Designer

The activity designer for the sample is similar in appearance to the designer provided for the built-in ForEach activity. The designer appears in the toolbox in the Samples, Non-Generic Activities category. The designer is named ForEachWithBodyFactory in the toolbox, because the activity exposes an IActivityTemplateFactory in the toolbox, which creates the activity with a properly configured ActivityAction.

public sealed class ForEachWithBodyFactory : IActivityTemplateFactory
{
    public Activity Create(DependencyObject target)
    {
        return new Microsoft.Samples.Activities.Statements.ForEach()
        {
            Body = new ActivityAction<object>()
            {
                Argument = new DelegateInArgument<object>()
                {
                    Name = "item"
                }
            }
        };
    }
}

To run this sample

  1. Set the project of your choice as the start-up project of the solution:

    1. CodeTestClient shows how to use the activity using code.

    2. DesignerTestClient shows how to use the activity within the designer.

  2. Build and run the project.

Ee834519.Important(en-us,VS.100).gif Note:
The samples may already be installed on your computer. Check for the following (default) directory before continuing.

<InstallDrive>:\WF_WCF_Samples

If this directory does not exist, go to Windows Communication Foundation (WCF) and Windows Workflow Foundation (WF) Samples for .NET Framework 4 to download all Windows Communication Foundation (WCF) and WF samples. This sample is located in the following directory.

<InstallDrive>:\WF_WCF_Samples\WF\Scenario\ActivityLibrary\NonGenericForEach