Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
.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 показывает, как использовать активность в конструкторе.
Соберите проект и запустите его.