Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по ООП (язык C#).pdf
Скачиваний:
190
Добавлен:
16.05.2015
Размер:
1.54 Mб
Скачать

Чернов Э. А.

- 106 -

Лекции по языку C# v 2.3

Операции с коллекциями

Операция Concat

Операция Concat объединяет две входные последовательности в одну выходную последовательность. Сначала в выходную последовательность переписывается первая последовательность, а после нее вторая. Ниже приведен пример

var seq1 =Enumerable.Range( 5,6);// Формирование 1-й последовательности var seq2 =Enumerable.Range( 7,6);// Формирование 2-й последовательности var comseq = seq1.Concat(seq2);// Объединение последовательностей foreach (int value in comseq)

Console.Write(" {0}", value);

var groups = lst.GroupBy(e => e.grp);

В результате получается

Операция Union

Операция Union объединяет две входные последовательностей, удаляя из выходной последовательности повторяющиеся элементы. В обобщенных коллекциях эквивалентность элементов определяется методами GetHashCode и Equals. Если в предыдущем примере операцию Concat заменить операцией Union, то

var comseq = seq1.Union(seq2);//

В результате получается

Получить последовательность без повторяющихся элементов можно с помощью операции Distinct, Except позволяет исключить повторяющиеся элементы, а Intersect включить повторяющиеся элементы

Преобразование

С помощью запросов можно преобразовывать необобщенные коллекции к требуемому типу. Для этого просматривают содержимое необобщенной коллекции с помощью операции OfType<T>(), отфильтровывая при этом элементы заданного типа.

При вызове метода OfType<T>() для необобщенной коллекции, реализующей интерфейс IEnumerable и содержащей разнотипные элементы (например, ArrayList), можно извлекать объекты, совместимые с IEnumerable<T> и сохранять их в переменной типа var.

В приведенном ниже примере список типа проинициализирован целыми и дробными числами, а также строками. С помощью запроса myLst.OfType<int>() из списка выбираются все целые числа, а с помощью запроса myLst.OfType<string>() из списка выбираются строки.

class Program

{

static void Main(string[ ] args)

Чернов Э. А.

- 107 -

Лекции по языку C# v 2.3

{

ArrayList myLst= new ArrayList ();

myLst.AddRange (new object [ ] {210, 21.5, false, “Акула”, 120, 81, “Skype”, 0.7, "Афанасий",15 });

var myNum = myLst.OfType<int>();

//Выведет на консоль 10, 400 и 8. Console.WriteLine("Список целых чисел"); foreach (int n in myNum)

{

Console.Write(" {0}", n) ;

}

Console.WriteLine("\nСписок строк");

var myString = myLst.OfType<string>();// я

//Выведет на консоль 10, 400 и 8. foreach (string s in myString)

{

Console.Write(" {0}", s);

}

Console.ReadKey();

}

}

Результат выполнения программы имеет вид (обратите внимание, дробные числа в список не попали):

Троел Ниже показан новый метод, который заполняет ArrayList множеством объектов Саг (не забудьте импортировать пространство имен System.Collections в файл

Program.cs).

public class Car

{

public string PetName; public string Color; public int Speed ; public string Make; public Car() { }

public Car(string p, string c, int s, string m)

{

PetName = p; Color = c; Speed = s; Make = m;

}

}

class Program

{

Чернов Э. А.

- 108 -

Лекции по языку C# v 2.3

static void Main(string[] args)

{

Console. WriteLine ("***** LINQ no ArrayList *****");

//Необобщенная коллекция автомобилей ArrayList () 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 в тип, совместимый с 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);

}

Console.ReadKey();

}

}

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

В приведенных примерах преобразование к интерфейсу явно не видно, хотя он и реализован в операторе foreach.

Операция ToList создает List типа Т из входной последовательности типа Т. Эта операция имеет один прототип, описанный ниже:

public static List<T> ToList<T>( this.IEnumerable<T> source);

Данная операция принимает последовательность по имени source элементов типа Т и возвращает список List элементов типа Т. Ниже демонстрируется применение операции

string[] cars = { "Alfa Romeo", "Aston Martin", "Audi", "Nissan", "Chevrolet", "Chrysler", "Dodge", "BMW", "Ferrari", "Bentley", "Ford", "Lexus", "Mercedes", "Toyota", "Volvo", "Subaru", "Жигули :)"};

Console.WriteLine("\nСписок автомобилей"); List<string> auto = cars.ToList();

foreach (string s in auto) Console.Write(s + " ");

Чернов Э. А.

- 109 -

Лекции по языку C# v 2.3

В приведенном коде используется массив, состоящий из названий машин. Этот массив преобразуется в список List<string>. Такое преобразование может применяться для объединения последовательностей.

Объединение последовательностей

Операция Join выполняет внутреннее соединение по эквивалентности двух последовательностей на основе ключей, извлеченных из каждого элемента этих последовательностей. Операция Join имеет один прототип, описанный ниже:

public static IEnumerable<V> Join<T, U, K, V>( this IEnumerable<T> outer, IEnumerable<U> inner,

Func<T, K> outerKeySelector, Func<U, K> innerKeySelector, Func<T, U, V> resultSelector);

Обратите внимание, что первый аргумент метода имеет имя outer. Поскольку это расширяющий метод, последовательность, на которой вызывается операция Join, будет называться внешней последовательностью.

Операция Join возвращает объект, который при перечислении сначала проходит последовательность inner элементов типа и, вызывая метод innerKeySelector по одному разу для каждого элемента и сохраняя элемент, на который ссылается его ключ, в хеш-таблице. Затем он проходит последовательность outer элементов типа Т. По мере того, как возвращаемый объект перечисляет каждый объект последовательности outer, он вызывает Tметод outerKeySelectorT для получения ключа и извлекает соответствующий элемент последовательности inner из хеш-таблицы, используя этот ключ.

Для каждой соответствующей пары элементов из последовательности outer и inner возвращаемый объект вызывает метод resultSelector, передавая ему и элемент outer, и соответствующий ему элемент inner. Метод resultSelector вернет экземпляр объекта типа V, который возвращаемый объект поместит в выходную последовательность типа V.

Порядок элементов последовательности outer сохраняется, равно как и порядок элементов inner в пределах каждого элемента outer.

FirstOrDefault

Операция First вызывает исключительную ситуацию, если элемент не найден.

Операция FirstOrDefault подобна First во всем, кроме поведения, когда элемент не найден (возвращает значение null). Эта операция имеет два прототипа, описанные ниже:

Первый прототип FirstOrDefault public static Т FirstOrDefault<T> (

this IEnumerable<T> source);

Эта версия прототипа FirstOrDefault возвращает первый элемент, найденный во входной последовательности. Если последовательность пуста, возвращается