// Трансформировать ArrayList в тип, совместимый c IEnumerable.

  var myCarsEnum = myCars.OfType();

  // Создать выражение запроса, нацеленное на совместимый с IEnumerable тип.

  var fastCars = from c in myCarsEnum where c.Speed > 55 select c;

  foreach (var car in fastCars)

  {

    Console.WriteLine("{0} is going too fast!", car.PetName);

  }

}

Аналогично предшествующим примерам этот метод, вызванный в операторах верхнего уровня, отобразит только имена Henry и Daisy, основываясь на формате запроса LINQ.

<p id="AutBody_Root499">Фильтрация данных с использованием метода OfТуре<Т>()</p>

Как вы уже знаете, необобщенные типы способны содержать любые комбинации элементов, поскольку члены этих контейнеров (вроде ArrayList) прототипированы для приема System.Object. Например, предположим, что ArrayList содержит разные элементы, часть которых являются числовыми. Получить подмножество, состоящее только из числовых данных, можно с помощью метода OfТуре<Т>(), т.к. во время итерации он отфильтрует элементы, тип которых отличается от заданного:

static void OfTypeAsFilter()

{

  // Извлечь из ArrayList целочисленные значения.

  ArrayList myStuff = new ArrayList();

  myStuff.AddRange(new object[] { 10, 400, 8, false, new Car(), "string data" });

  var myInts = myStuff.OfType();

  // Выводит 10, 400 и 8.

  foreach (int i in myInts)

  {

    Console.WriteLine("Int value: {0}", i);

  }

}

К настоящему моменту вы уже умеете применять запросы LINQ к массивам, а также обобщенным и необобщенным коллекциям. Контейнеры подобного рода содержат элементарные типы C# (целочисленные и строковые данные) и специальные классы. Следующей задачей будет изучение многочисленных дополнительных операций LINQ, которые могут использоваться для построения более сложных и полезных запросов.

<p id="AutBody_Root500">Исследование операций запросов LINQ</p>

В языке C# предопределено порядочное число операций запросов. Некоторые часто применяемые из них перечислены в табл. 13.2. В дополнение к неполному списку операций, приведенному в табл. 13.3, класс System.Linq.Enumerable предлагает набор методов, которые не имеют прямого сокращенного обозначения в виде операций запросов С#, а доступны как расширяющие методы. Эти обобщенные методы можно вызывать для трансформации результирующего набора разными способами (Reverse<>(), ToArray<>(), ToList<>() и т.д.). Некоторые из них применяются для извлечения одиночных элементов из результирующего набора, другие выполняют разнообразные операции над множествами (Distinct<>(), Union<>(), Intersect<>() и т.п.), а есть еще те, что агрегируют результаты (Count<>(), Sum<>(), Min<>(), Мах<>() и т.д.).

Чтобы приступить к исследованию более замысловатых запросов LINQ, создайте новый проект консольного приложения по имени FunWithLinqExpressions и затем определите массив или коллекцию некоторых выборочных данных. В проекте FunWithLinqExpressions вы будете создавать массив объектов типа ProductInfo, определенного следующим образом:

namespace FunWithLinqExpressions

{

  class ProductInfo

  {

    public string Name {get; set;} = "";

    public string Description {get; set;} = "";

    public int NumberInStock {get; set;} = 0;

    public override string ToString()

      => $"Name={Name}, Description={Description},

         Number in Stock={NumberInStock}";

  }

}

Теперь заполните массив объектами ProductInfo в вызывающем коде:

Console.WriteLine("***** Fun with Query Expressions *****\n");

// Этот массив будет основой для тестирования...

ProductInfo[] itemsInStock = new[] {

  new ProductInfo{ Name = "Mac's Coffee",

    Description = "Coffee with TEETH", NumberInStock = 24},

  new ProductInfo{ Name = "Milk Maid Milk",

Перейти на страницу:

Похожие книги