Expresiones (WF)

Una expresión de Windows Workflow Foundation (WF) es cualquier actividad que devuelve un resultado. Todas las actividades de expresión derivan indirectamente de Activity<TResult>, que contiene una propiedad OutArgument denominada Result como valor devuelto de la actividad. WF incluye una gran variedad de actividades de expresión, desde sencillas, como VariableValue<T> y VariableReference<T>, que proporcionan acceso a una única variable de flujo de trabajo mediante actividades de operador, hasta actividades complejas, como VisualBasicReference<TResult> y VisualBasicValue<TResult>, que proporcionan acceso a todo el lenguaje Visual Basic para generar el resultado. Las actividades de expresión adicionales se pueden crear al derivar de CodeActivity<TResult> o NativeActivity<TResult>.

Usar expresiones

El diseñador de flujo de trabajo usa VisualBasicValue<TResult> y VisualBasicReference<TResult> para todas las expresiones en proyectos de Visual Basic, y CSharpValue<TResult> y CSharpReference<TResult> para expresiones en los proyectos de flujo de trabajo de C#.

Nota

La compatibilidad con las expresiones de C# en proyectos de flujo de trabajo se incorporó en .NET Framework 4.5. Para obtener más información, consulte Expresiones de C#.

Los flujos de trabajo generados por el diseñador se guardan en XAML, donde las expresiones se adjuntan en corchetes, como en el siguiente ejemplo.

<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>

Al definir un flujo de trabajo en el código, se puede usar cualquier actividad de expresión. El siguiente ejemplo muestra el uso de una composición de actividades de operador para sumar tres números:

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

El mismo flujo de trabajo se puede expresar de una forma más compacta usando expresiones lambda de C#, como se muestra en el siguiente ejemplo:

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

Extender las expresiones disponibles con actividades de expresión personalizadas

Las expresiones de .NET Framework 4.6.1 son extensibles, lo que permite crear actividades de expresión adicionales. En el siguiente ejemplo se muestra una actividad que devuelve una suma de tres valores enteros.

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

Con esta nueva actividad, puede volver a escribir el flujo de trabajo anterior que sumó tres valores, como se muestra en el siguiente ejemplo:

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

Para obtener más información sobre el uso de expresiones en el código, consulte Crear flujos de trabajo, actividades y expresiones mediante código imperativo.