Операции преобразования

63

Ранее уже упоминалось, что можно получить объект 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);
            }
Использование операции OfType

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 - Запросы без результатов.

Пройди тесты
Лучший чат для C# программистов