Операции преобразования
63LINQ --- PLINQ --- Операции преобразования
Ранее уже упоминалось, что можно получить объект ParallelQuery из унаследованной коллекции с помощью метода AsParallel, но для получения объекта ParallelQuery<T>, который можно использовать с PLINQ, понадобится предпринять дополнительные действия. В этой статье рассматриваются операции, позволяющие выполнять нужные преобразования.
Cast
Операция Cast преобразует ParallelQuery в ParallelQuery<T>. Должен быть указан тип, и если во входной последовательности есть какие-то элементы, которые не относятся к типу Т, будет сгенерировано исключение.
Операция Cast имеет один прототип. Чтобы создать ParallelQuery<string>, необходимо вызвать Cast<string>(). Если нужен ParallelQuery<MyObject>, следует вызвать Cast<MyObject>():
public static ParallelQuery<T> Cast<T>(
this ParallelQuery source)
Ниже демонстрируется применение операции Cast для использования унаследованной коллекции в качестве источника для запроса PLINQ. Операция AsParallel применяется к ArrayList и затем вызывается Cast<string> для создания объекта ParallelQuery<string>, используемого в запросе PLINQ:
ArrayList list = new ArrayList() {"Nissan", "Aston Martin", "Chevrolet", "Alfa Romeo", "Chrysler", "Dodge", "BMW",
"Ferrari", "Audi", "Bentley", "Ford", "Lexus", "Mercedes", "Toyota", "Volvo", "Subaru", "Жигули :)"};
IEnumerable<string> auto = list
.AsParallel()
.Cast<string>()
.Where(p => p.Contains("o"))
.Select(p => p);
foreach (string s in auto)
Console.WriteLine("Совпадение: " + s);
Компиляция и запуск кода дает следующие результаты:

OfType
Операция OfType создает ParallelQuery<T> из ParallelQuery, выбирая только те элементы последовательности, которые относятся к типу Т. Это позволяет выборочно использовать элементы из унаследованной коллекции, содержащей смешанные типы, не беспокоясь об исключениях, которые могут возникнуть в случае применения операции Cast.
Операция OfType имеет один прототип:
public static ParallelQuery<T> OfType<T>(
this ParallelQuery source)
Ниже содержится пример использования этой операции. Выбираемый тип указывается в угловых скобках. Если, например, необходимо получить ParallelQuery<string>, то следует вызвать OfType<string>. В этом коде создается унаследованная коллекция, содержащую смесь типов, и затем используется операция OfType для создания экземпляра ParallelQuery<string>, который содержит строковые значения из коллекции. После этого объект ParallelQuery<string> при меняется в запросе PLINQ:
ArrayList list = new ArrayList();
list.Add("Alex");
list.Add(23);
list.Add("Elena");
list.Add(DateTime.Now);
list.Add("Petr");
list.Add(new string[] { "apple", "orange" });
IEnumerable<string> results = list
.AsParallel()
.OfType<string>()
.Select(p => p);
foreach (string s in results)
{
Console.WriteLine("Match: {0}", s);
}

ForAll
Операция ForAll уникальна для PLINQ и не имеет эквивалента в LINQ to Objects. Эта операция позволяет указывать действие, которое будет выполнено над каждым элементом в исходной последовательности данных при выполнении запроса.
У операции ForAll один прототип. Аргументом является экземпляр System.Action, который будет выполнен над каждым элементом последовательности. Возвращать результирующее значение из Action нельзя:
public static void ForAll<T>(
this ParallelQuery<T> source,
Action<T> action)
Дополнительную информацию и примеры применения операции ForAll смотрите в статье Parallel LINQ - Запросы без результатов.