Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
.NET Framework 4.6.1 поставляется с набором действий управления потоком на панели элементов, включая ForEach<T>, который позволяет выполнять итерации по коллекциям IEnumerable<T>.
ForEach<T> требует, чтобы его Values свойство было типом IEnumerable<T>. Это предотвращает итерацию пользователей над структурами данных, реализующими IEnumerable<T> интерфейс (например, ArrayList). Необобщённая версия ForEach<T> преодолевает это требование, повышая сложность на уровне среды выполнения для обеспечения совместимости типов значений в коллекции.
В примере NonGenericForEach показано, как реализовать не универсальное ForEach<T> действие и его конструктор. Это действие можно использовать для итерации ArrayList.
Операция ForEach
Инструкция C#/Visual Basic foreach перечисляет элементы коллекции, выполняя внедренную инструкцию для каждого элемента коллекции. Эквивалентные действия foreach в WF — это ForEach<T> и ParallelForEach<T>. Действие ForEach<T> содержит список значений и текст. Во время выполнения список итерируется, и тело выполняется для каждого значения в списке.
В большинстве случаев универсальная версия действия должна быть предпочтительным решением, так как она охватывает большинство сценариев, в которых он будет использоваться, и обеспечивает проверку типов во время компиляции. Не универсальная версия может использоваться для итерации типов, реализующих не универсальный IEnumerable интерфейс.
Определение класса
В следующем примере кода показано определение не универсального ForEach действия.
[ContentProperty("Body")]
public class ForEach : NativeActivity
{
[RequiredArgument]
[DefaultValue(null)]
InArgument<IEnumerable> Values { get; set; }
[DefaultValue(null)]
[DependsOn("Values")]
ActivityAction<object> Body { get; set; }
}
Содержание (необязательно) выполняется для каждого элемента в коллекции и имеет тип ActivityActionObject. Каждый отдельный элемент передается в Body через его Argument свойство.
Значения (необязательно) Коллекция элементов, которые итерируются. Обеспечение того, чтобы все элементы коллекции были совместимыми типами во время выполнения.
Пример использования forEach
В следующем коде показано, как использовать действие ForEach в приложении.
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)))
}
}
};
| Состояние | Сообщение | Степень серьезности | Тип исключения |
|---|---|---|---|
Значения: null |
Значение для обязательного аргумента действия 'Значение' не было предоставлено. | Ошибка | InvalidOperationException |
Конструктор «forEach»
Конструктор действий в примере по внешнему виду похож на конструктор, предоставленный для встроенного ForEach<T> действия. Конструктор отображается на панели элементов в категории «Примеры», «Неуниверсальные действия». Конструктор называется ForEachWithBodyFactory на панели элементов, потому что это действие предоставляет IActivityTemplateFactory, который создает действие с правильно настроенным 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"
}
}
};
}
}
Чтобы запустить этот пример
Задайте проект вашего выбора в качестве начального проекта решения:
CodeTestClient показывает, как использовать действие с помощью кода.
DesignerTestClient показывает, как использовать активность в конструкторе.
Соберите проект и запустите его.