表达式

本主题适用于 Windows Workflow Foundation 4。

Windows Workflow Foundation (WF) 表达式是返回结果的任何活动。所有表达式活动都间接从 Activity 派生,该活动包含一个作为活动返回值名为 ResultOutArgument 属性。WF 附带了大量表达式活动,从简单的活动(如通过运算符活动提供单个工作流变量的访问的 VariableValueVariableReference)到复杂活动(如提供对所有 Visual Basic 语言范围的访问以生成结果的 VisualBasicReferenceVisualBasicValue)。可以通过从 CodeActivityNativeActivity 派生来创建其他表达式活动。

使用表达式

工作流设计器对所有表达式都使用 VisualBasicValueVisualBasicReference。这就是必须在设计器的表达式文本框中使用 Visual Basic 语法的原因。设计器生成的工作流保存在 XAML 中,其中表达式位于方括号中,如以下示例所示。

<Sequence xmlns="https://schemas.microsoft.com/netfx/2009/xaml/activities" xmlns:x="https://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>

在代码中定义工作流时,可以使用所有表达式活动。下面的示例演示如何使用运算符活动的组合添加三个数字。

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)
                }
            }
        }
    }
};

使用 C# lambda 表达式可以更简洁地表示同一工作流,如下面的示例所示。

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))
        }
    }
};

还可以使用 Visual Basic 表达式活动表示该工作流,如下面的示例所示。

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"))
        }
    }
};

使用自定义表达式活动扩展可用的表达式

可以扩展 .NET Framework 4 中的表达式,从而允许创建其他表达式活动。下面的示例演示返回三个整数值之和的活动。

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);
        }
    }
}

通过这个新活动,您可以重新编写前面添加三个值的工作流,如下面的示例所示。

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)
                }
            }
        }
    }
};

有关在代码中使用表达式的更多信息,请参见使用命令性代码创作工作流