Expressions

A Windows Workflow Foundation (WF) expression is any activity that returns a result. All expression activities derive indirectly from Activity<TResult>, which contains an OutArgument property named Result as the activity’s return value. WF ships with a wide range of expression activities from simple ones like VariableValue<T> and VariableReference<T>, which provide access to single workflow variable through operator activities, to complex activities such as VisualBasicReference<TResult> and VisualBasicValue<TResult> that offer access to the full breadth of Visual Basic language to produce the result. Additional expression activities can be created by deriving from CodeActivity<TResult> or NativeActivity<TResult>.

Using Expressions

Workflow designer uses VisualBasicValue<TResult> and VisualBasicReference<TResult> for all expressions in Visual Basic projects, and CSharpValue<TResult> and CSharpReference<TResult> for expressions in C# workflow projects.

Note

Support for C# expressions in workflow projects was introduced in .NET Framework 4.5. For more information, see C# Expressions.

Workflows produced by designer are saved in XAML, where expressions appear enclosed in square brackets, as in the following example.

<Sequence xmlns="http://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">  
  <Sequence.Variables>  
    <Variable x:TypeArguments="x:Int32" Default="1" Name="a" />  
    <Variable x:TypeArguments="x:Int32" Default="2" Name="b" />  
    <Variable x:TypeArguments="x:Int32" Default="3" Name="c" />  
    <Variable x:TypeArguments="x:Int32" Default="0" Name="r" />  
  </Sequence.Variables>  
  <Assign>  
    <Assign.To>  
      <OutArgument x:TypeArguments="x:Int32">[r]</OutArgument>  
    </Assign.To>  
    <Assign.Value>  
      <InArgument x:TypeArguments="x:Int32">[a + b + c]</InArgument>  
    </Assign.Value>  
  </Assign>  
</Sequence>  

When defining a workflow in code, any expression activities can be used. The following example shows the usage of a composition of operator activities to add three numbers.

Variable<int> a = new Variable<int>("a", 1);  
Variable<int> b = new Variable<int>("b", 2);  
Variable<int> c = new Variable<int>("c", 3);  
Variable<int> r = new Variable<int>("r", 0);  

Sequence w = new Sequence  
{  
    Variables = { a, b, c, r },  
    Activities =   
    {  
        new Assign {  
            To = new OutArgument<int>(r),  
            Value = new InArgument<int> {  
                Expression = new Add<int, int, int> {  
                    Left = new Add<int, int, int> {  
                        Left = new InArgument<int>(a),  
                        Right = new InArgument<int>(b)  
                    },  
                    Right = new InArgument<int>(c)  
                }  
            }  
        }  
    }  
};  

The same workflow can be expressed more compactly by using C# lambda expressions, as shown in the following example.

Variable<int> a = new Variable<int>("a", 1);  
Variable<int> b = new Variable<int>("b", 2);  
Variable<int> c = new Variable<int>("c", 3);  
Variable<int> r = new Variable<int>("r", 0);  

Sequence w = new Sequence  
{  
    Variables = { a, b, c, r },  
    Activities =   
    {  
        new Assign {  
            To = new OutArgument<int>(r),  
            Value = new InArgument<int>((ctx) => a.Get(ctx) + b.Get(ctx) + c.Get(ctx))  
        }  
    }  
};  

The workflow can also be expressed by using Visual Basic expression activities, as shown in the following example.

Variable<int> a = new Variable<int>("a", 1);  
Variable<int> b = new Variable<int>("b", 2);  
Variable<int> c = new Variable<int>("c", 3);  
Variable<int> r = new Variable<int>("r", 0);  

Sequence w = new Sequence  
{  
    Variables = { a, b, c, r },  
    Activities =   
    {  
        new Assign {  
            To = new OutArgument<int>(r),  
            Value = new InArgument<int>(new VisualBasicValue<int>("a + b + c"))  
        }  
    }  
};  

Extending Available Expressions with Custom Expression Activities

Expressions in .NET Framework 4.6.1 are extensible allowing for additional expression activities to be created. The following example shows an activity that returns a sum of three integer values.

using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Activities;  

namespace ExpressionsDemo  
{  
    public sealed class AddThreeValues : CodeActivity<int>  
    {  
        public InArgument<int> Value1 { get; set; }  
        public InArgument<int> Value2 { get; set; }  
        public InArgument<int> Value3 { get; set; }  

        protected override int Execute(CodeActivityContext context)  
        {  
            return Value1.Get(context) +   
                   Value2.Get(context) +   
                   Value3.Get(context);  
        }  
    }  
}  

With this new activity you can rewrite the previous workflow that added three values as shown in the following example.

Variable<int> a = new Variable<int>("a", 1);  
Variable<int> b = new Variable<int>("b", 2);  
Variable<int> c = new Variable<int>("c", 3);  
Variable<int> r = new Variable<int>("r", 0);  

Sequence w = new Sequence  
{  
    Variables = { a, b, c, r },  
    Activities =   
    {  
        new Assign {  
            To = new OutArgument<int>(r),  
            Value = new InArgument<int> {  
                Expression = new AddThreeValues() {  
                    Value1 = new InArgument<int>(a),  
                    Value2 = new InArgument<int>(b),  
                    Value3 = new InArgument<int>(c)  
                }  
            }  
        }  
    }  
};  

For more information about using expressions in code, see Authoring Workflows, Activities, and Expressions Using Imperative Code.