Язык программирования C#9 и платформа .NET5
При вызове метода
на объекте необобщенной коллекции (наподобиеOfТуре<Т>()) нужно просто указать тип элемента внутри контейнера, чтобы извлечь совместимый сArrayListобъект. Сохранить этот элемент данных в коде можно посредством неявно типизированной переменной.IEnumerable<T>Взгляните на показанный ниже новый метод, который заполняет
набором объектовArrayList(не забудьте импортировать пространство именCarв начале файлаSystem.Collections):Program.csstatic void LINQOverArrayList(){Console.WriteLine("***** LINQ over ArrayList *****");// Необобщенная коллекция объектов Car.ArrayList myCars = new ArrayList() {new Car{ PetName = "Henry", Color = "Silver", Speed = 100, Make = "BMW"},new Car{ PetName = "Daisy", Color = "Tan", Speed = 90, Make = "BMW"},new Car{ PetName = "Mary", Color = "Black", Speed = 55, Make = "VW"},new Car{ PetName = "Clunker", Color = "Rust", Speed = 5, Make = "Yugo"},new Car{ PetName = "Melvin", Color = "White", Speed = 43, Make = "Ford"}};// Трансформировать ArrayList в тип, совместимый c IEnumerable<T>.var myCarsEnum = myCars.OfType<Car>();// Создать выражение запроса, нацеленное на совместимый с IEnumerable<T> тип.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, основываясь на формате запроса LINQ.DaisyФильтрация данных с использованием метода OfТуре<Т>()
Как вы уже знаете, необобщенные типы способны содержать любые комбинации элементов, поскольку члены этих контейнеров (вроде
) прототипированы для приема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<int>();// Выводит 10, 400 и 8.foreach (int i in myInts){Console.WriteLine("Int value: {0}", i);}}К настоящему моменту вы уже умеете применять запросы LINQ к массивам, а также обобщенным и необобщенным коллекциям. Контейнеры подобного рода содержат элементарные типы C# (целочисленные и строковые данные) и специальные классы. Следующей задачей будет изучение многочисленных дополнительных операций LINQ, которые могут использоваться для построения более сложных и полезных запросов.
Исследование операций запросов LINQ
В языке C# предопределено порядочное число операций запросов. Некоторые часто применяемые из них перечислены в табл. 13.2. В дополнение к неполному списку операций, приведенному в табл. 13.3, класс
предлагает набор методов, которые не имеют прямого сокращенного обозначения в виде операций запросов С#, а доступны как расширяющие методы. Эти обобщенные методы можно вызывать для трансформации результирующего набора разными способами (System.Linq.Enumerable,Reverse<>(),ToArray<>()и т.д.). Некоторые из них применяются для извлечения одиночных элементов из результирующего набора, другие выполняют разнообразные операции над множествами (ToList<>(),Distinct<>(),Union<>()и т.п.), а есть еще те, что агрегируют результаты (Intersect<>(),Count<>(),Sum<>(),Min<>()и т.д.).Мах<>()Чтобы приступить к исследованию более замысловатых запросов LINQ, создайте новый проект консольного приложения по имени
и затем определите массив или коллекцию некоторых выборочных данных. В проектеFunWithLinqExpressionsвы будете создавать массив объектов типаFunWithLinqExpressions, определенного следующим образом:ProductInfonamespace FunWithLinqExpressions{class ProductInfo{public string Name {get; set;} = "";
