You are on page 1of 12

МІНІСТЕРСТВО ОСВІТИ І НАУКИ УКРАЇНИ

НАЦІОНАЛЬНИЙ АВІАЦІЙНИЙ УНІВЕРСИТЕТ


Факультет кібербезпеки, комп’ютерної та програмної інженерії
Кафедра інженерії програмного забезпечення

Лабораторна робота №2
з дисципліни «Об’єктно-орієнтовне програмування»
«Дослідження колекцій та узагальнених колекцій С#»

Виконав студент:
групи ПІ-223
Черпак Володимир
Перевірив викладач:
Васильєва М.Д.

Київ 2020
Мета роботи – дослідити класи-колекції та узагальнені колекції у мові
програмування С#.
Завдання

1. Описати клас, заданий варіантом у мові програмування С# (табл. 1).

2. Створити список об’єктів класу, вказаного в п.1, використовуючи будь-яку


бібліотечну узагальнену (Generic), звичайну (non-generic) колекцію С#, а також
масив. Продемонструвати основні операції з колекціями та масивами: додавання,
видалення, оновлення, пошук елементу та прохід по

набору даних. Порівняти поведінку та пояснити відмінності. Максимальна оцінка


за виконання завдання 1-2 - «задовільно».

3. Створити бінарне дерево об'єктів класу, вказаного в п.1. При цьому для бінарного
дерева передбачити можливість зберігати дані будь-якого типу (створити
узагальнений тип). Елементами дерева не можуть бути структури. Максимальна
оцінка за виконання завдання 1-3 - «добре».

4. Доповнити бінарне дерево з п.3 операцію порівняння (використати узагальнені


типи та інтерфейси IComparer<T> і/чи IComparable<T>). Продемонструвати
функціонал, реалізований з інтерфейсів порівняння через виклик методів
сортування. А також реалізувати власний ітератор, використовуючи інтерфейси
<IEnumerable> та <IEnumerator>. Обхід дерева реалізувати відповідно до віріанту з
табл 1 (колонка «Порядок обходу дерева*»). Максимальна оцінки за виконання
завдань 1-4 – «відмінно».
Варіант №12

Лістинг коду:
Class Account
{
public class Account
{

public Account(int code, double sum)//Конструктор с параметрами для работы со свойствами


счёта
{
Code = code;
Sum = sum;
}

public int Code { get; set; }//Номер счёта


public double Sum { get; set; }//Сумма на нём

public override string ToString()


{
return $"{Code} - {Sum}";
}
}
}

Class AccountService
{
public class AccountService : IAccountService
{
private IEnumerable<Account> _collection;

public AccountService(IEnumerable<Account> collection)


{
_collection = collection;
}

public string GetInfo()


{
string info = "";
for (int i = 0; i < _collection.Count(); i++)
{
info += _collection.ElementAt(i)?.ToString() + '\n';
}

return info;
}

public void Replenish()// метод пополнения счёта


{
Console.WriteLine("Какой счёт хотите пополнить?(0-3)");

string rahunok0 = Console.ReadLine();

int rahunok = Int32.Parse(rahunok0);


try// обработчик исключений (если введен счёт , которого не существует ----> блок
catch)
{
var p = _collection.ElementAt(rahunok);// в переменную p запишем елемент который
выбрали и проводим с ним действия
Console.WriteLine("Укажите cуму для пополнения:");
string plus = Console.ReadLine();
double summa = Double.Parse(plus);
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine($"Счёт #{p.Code} пополнен на {summa} грн");
p.Sum = p.Sum + summa;
Console.WriteLine($"Состояние счёта #{p.Code} : {p.Sum} грн");//выведет
состояние счёта который пополняли , тоесть под переменной p
}

catch (ArgumentOutOfRangeException)
{
Console.WriteLine("Такого счёта не существует!");
}

public void Withdraw()// метод снятия налички


{
Console.WriteLine("С какого счёта хотите снять деньги?(0-3)");

string rahunok0 = Console.ReadLine();

int rahunok = Int32.Parse(rahunok0);

try// обработчик исключений (если введен счёт , которого не существует ----> блок
catch)
{

var p = _collection.ElementAt(rahunok);// в переменную p запишем елемент который


выбрали и проводим с ним действия
Console.WriteLine("Укажите cуму для снятия:");// указываем суму для снятия
string minus = Console.ReadLine();
double summa = Double.Parse(minus);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine($"Со счёта {p.Code} было снято {summa} грн");
p.Sum = p.Sum - summa;// расчёт сумы на счёту после снятия денег
Console.WriteLine($"Состояние счёта #{p.Code} : {p.Sum} грн");

if (p.Sum < 0)// если сума после снятия денег 0 ---- > красит красным
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Состояние вашего счёта меньше 0 !");
Console.WriteLine("Пополните его!");
}
}
catch (ArgumentOutOfRangeException)//если счёта не существует
{
Console.WriteLine("Такого счёта не существует!");
}
}

public void Transfer()// метод перевода денег между счетами


{
Console.WriteLine("С какого счёта хотите перевести деньги?(0-3)");
string rahunok0 = Console.ReadLine();
int rahunok1 = Int32.Parse(rahunok0);
Console.WriteLine("На какой счёт хотите перевести деньги?(0-3)");
string rahunok01 = Console.ReadLine();
int rahunok2 = Int32.Parse(rahunok01);

try
{
var p1 = _collection.ElementAt(rahunok1);
var p2 = _collection.ElementAt(rahunok2);
Console.WriteLine("Укажите cуму для перевода:");
string minus = Console.ReadLine();
double summa = Double.Parse(minus);
p1.Sum -= summa;//отнимаем со счёта суму
p2.Sum += summa;//прибавляем её на другой счёт
Console.WriteLine($"Со счёта {p1.Code} было снято {summa} грн и переведено на
счёт {p2.Code} ");
Console.WriteLine($"Состояние счёта #{p1.Code} : {p1.Sum} грн");
Console.WriteLine($"Состояние счёта #{p2.Code} : {p2.Sum} грн");

if (p1.Sum < 0 || p2.Sum < 0)//если состояние одного из счётов меньше 0


{
Console.WriteLine("Состояние счёта меньше 0 !");
Console.WriteLine("Пополните его!");
}
}

catch (ArgumentOutOfRangeException)
{
Console.WriteLine("Данный перевод невозможен!");
Console.WriteLine("Счёт не найден!");
}

}
}
}
Class Vector
{
public class Vector : IVector
{
int index = -1;
private readonly Account[] array;

public int Count => array.Count();

public object SyncRoot => new object();

public bool IsSynchronized => true;

public Vector(int size)


{
array = new Account[size];
}

public bool Add(Account goods) // добавление в массив


{
if (IsFull() == true) // если полный массив - не добавлять
{
return false;
}
else
{
array[++index] = goods; // если не полон , то на индекс вставить елемент
return true;
}
}

public Account Delete(int index) // удалить с индкса елемент


{
if (IsEmpty() == false && array[index] != null)
{
Account temp = array[index];
array[index] = null;
return temp;
}
else
{
return null;
}
}

public bool IsEmpty() // проверка на пустоту


{
if (index < 0)
{
return true;
}
else
{
return false;
}
}

public bool IsFull() // проверка на заполненость


{
if (array.Length < index)
{
return true;
}
else
{
return false;
}
}

public bool Update(Account goods) // обновлять елемент , если имя совпадает


{
for (int i = 0; i < array.Length; i++)
{
if (array[i].Code == goods.Code)
{
array.SetValue(goods, i);
}
}

return true;
}

public void CopyTo(Array array, int index)


{
// Does nothing
}

public IEnumerator GetEnumerator()


{
return GetEnumerator();
}

IEnumerator<Account> IEnumerable<Account>.GetEnumerator()
{
for (int i = 0; i < array.Count(); i++)
{
yield return array[i];

}
}
}
}
Class DemonstrationService
{
public class DemonstrationService
{
private IAccountService _accountService;

public void Demonstrate_Collection()


{
var accounts = new List<Account>();

accounts.Add(new Account(516857458, 500));


accounts.Add(new Account(516857438, 500));
accounts.Add(new Account(51685758, 500));
accounts.Add(new Account(516857358, 500));

_accountService = new AccountService(accounts);

ShowCollectionWithCaption("Accounts");

_accountService.Replenish();

ShowCollectionWithCaption("Accounts");

_accountService.Withdraw();

accounts.Remove(accounts.Where(x => x?.Code == 516857438).FirstOrDefault());


ShowCollectionWithCaption("Accounts after removing one element");

Console.WriteLine("Founded:");
var search = accounts.Where(x => x?.Code == 516857438).FirstOrDefault();
Console.WriteLine(search?.ToString());

accounts.FindAll(x => x?.Code == 516857438).ForEach(x => x.Code = 00000);


ShowCollectionWithCaption("Accounts after updating one element: ");
}

public void Demonstrate_Array()


{
var accounts = new Vector(5);

accounts.Add(new Account(516857458, 500));


accounts.Add(new Account(516857438, 500));
accounts.Add(new Account(51685758, 500));
accounts.Add(new Account(516857358, 500));

_accountService = new AccountService(accounts);

ShowCollectionWithCaption("Accounts");
_accountService.Replenish();

ShowCollectionWithCaption("Accounts");

_accountService.Withdraw();

accounts.Delete(0);
accounts.Delete(0);
ShowCollectionWithCaption("Accounts after removing one element");

Console.WriteLine("Founded:");
var search = accounts.Where(x => x?.Code == 516857438).FirstOrDefault();
Console.WriteLine(search.ToString());

accounts.FirstOrDefault(x => x?.Code == 516857438).Code = 1111111;


ShowCollectionWithCaption("Accounts after updating one element: ");
}

private void ShowCollectionWithCaption(string caption)


{
Console.WriteLine();
Console.ForegroundColor = ConsoleColor.Green;
Console.WriteLine(caption);
Console.ForegroundColor = ConsoleColor.White;
Console.WriteLine();

Console.WriteLine(_accountService.GetInfo());
}

}
}
Class Program
{
class Program
{
static void Main(string[] args)
{
var demoService = new DemonstrationService();

CaptionShow("Array");
demoService.Demonstrate_Array();
CaptionShow("Collection");
demoService.Demonstrate_Collection();

Console.ReadKey();
}

public static void CaptionShow(string caption)


{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine(caption);
Console.ForegroundColor = ConsoleColor.White;
}
}
}
Контрольні запитання та завдання:
1. Дайте визначення колекції. Наведіть типи колекцій FCL.
Колекція - об'єкт, що містить набір пов'язаних об'єктів.
Collection - тип спеціалізованого класу в NET Framework для зберігання та пошуку
даних. Ці класи забезпечують підтримку стеків, черг і таблиць
Під Framework Class Library (FCL) колекції в основному розміщуються в просторі
імен System.Collections.
Призначення:
Вбудовані масиви Звичайні масиви, підтримувані CLR безпосередньо. У сумісних
CLR мовах вони є повноцінними об'єктами.
ArrayList - Є реалізацією абстракції списку на базі масиву, Дозволяє динамічно
змінювати розмір, додавати і видаляти елементи. По суті, динамічний масив, що
дозволяє зберігати посилання на об'єкти.
Hashtable - Реалізує абстракцію «словник» (Dictionary, колекцію пар «ключ-
значення») на основі алгоритму хеш-таблиці.
SortedList - Реалізація абстракції словника і списку на базі сортованого масиву.
Stack - Реалізує абстракцію «стек» - колекцію, що дозволяє здійснювати доступ до
елементів за принципом FILO (First In - Last Out, першим прийшов - останнім
пішов). Як сховище використовується масив.
Queue - Реалізує абстракцію «чергу» - колекцію, що дозволяє здійснювати доступ
до елементів за принципом FIFO (First In - First Out, першим прийшов - першим
пішов). Як сховище використовується масив.
BitArray - Дозволяє створювати бітові масиви і управляти ними.
В .NET Framework масив не відноситься до числа колекцій, хоча за своїм
призначенням масиви теж є колекціями. Масиви відокремлені від колекцій тому,
що вони підтримуються середовищем виконання безпосередньо.

2. Що таке операції «упаковка» і «розпаковка»? Наведіть приклади.


Довідкові типи (object, dynamic, string, class, interface, delegate) зберігаються в
керованій купі, типи значень (struct, enum; bool, byte, char, int, float, double) - в стеці
додатка (крім випадку, коли тип значення є полем класу). Перетворення типу
значень до посилального типу супроводжується неявній операцією упаковки
(boxing) - приміщення копії типу значень в клас-обгортку, екземпляр якого
зберігається в купі. Пакувальний тип генерується CLR і реалізує інтерфейси
зберігається типу значення. Перетворення посилального типу до типу значень
викликає операцію розпакування (unboxing) - витяг з упаковки копії типу значення і
приміщення її в стек.
• Коли будь-який значущий тип присвоюється до посилального типу даних,
значення переміщається з області стека в купу. Ця операція називається упаковкою.
• Коли будь-який контрольний тип присвоюється до значимого типу даних,
значення переміщається з області купи в стек. Це називається розпакуванням.
3. Наведіть основні інтерфейси, які успадковуються колекціями, та їх
призначення.
Название Описание

IEnumerable Предоставляет итератор, который поддерживает простой перебор элементов коллекции.

Определяет методы, позволяющие определить количество элементов в коллекции, а также


ICollection
методы синхронизации для коллекций.

Представляет интерфейс коллекции объектов, каждый из которых может быть получен по


IList
индексу. Также определяет методы модификации коллекции.

IDictionary Представляет интерфейс коллекции пар «ключ-значение».

ICloneable Определяет метод, позволяющий создать копию объекта

IComparer Определяет метод, осуществляющий сравнение двух объектов.

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


IEnumerator
Возвращается методом GetEnumerator интерфейса IEnumerable.

Используется при поиске и сортировке объектов. Может быть реализован типами, для
IComparable
которых определены операции сравнения.

IDictionaryEnumerator Позволяет перебрать элементы словаря.

IHashCodeProvider Определяет метод, позволяющий вычислить хэш-код для объекта.

4. Наведіть класи колекцій, які реалізують типову поведінку основних структур


даних.
 Queue
 Stack

5. Поясніть призначення нумератору колекцій.


Нумератор забезпечує стандартний послідовний доступ до елементів колекції.

6. Як реалізувати власний нумератор? В яких випадках він потрібний?


Все коллекции C# реализуют так называемые нумераторы, которые
поддерживают интерфейсы IEnumerator и IEnumerable. Каждая коллекция должна
реализовать интерфейс IEnumerable для возможности доступа к ее элементам с
помощью методов интерфейса IEnumerator. Нумератор используется также для
прохода по коллекции с помощью цикла foreach.

7. Дані якого формату зберігаються у хеш-таблиці?


Реализует абстракцию «словарь» (Dictionary, коллекцию пар «ключ-значение»)
на основе алгоритма хэш-таблицы.

8. Поясніть особливості узагальнених типів .Net.


Узагальнені типи (generic types) означають параметризовані типи. Вони здатні
створювати класи, інтерфейси, методи, в яких типи даних, що оперують в них,
специфікуються як параметри.

9. Поясніть сутність обмежень узагальнених типів.


Посилання, оператори, індексатори не можуть бути узагальненими.
Якщо узагальнений клас містить статичне поле, то кожен тип містить його власну
копію цього поля.

10. Що може бути реалізовано, як узагальнення в C#?


Посилання, оператори, індексатори не можуть бути узагальненими.

11. Порівняйте універсальні та узагальнені колекції.


Інтерфейси узагальнених колекцій відрізняються від неузагальнених двійників не
тільки наявністю універсального параметра T, але і самої функціональністю.
Більшість узагальнених класів колекцій дублюють неузагальнених класи колекцій.
Але якщо не треба зберігати об'єкти різних типів, то краще використовувати
узагальнені колекції.

12. Коли варто створювати власні класи колекцій?


Власні класи колекцій варто створювати тоді, коли необхідно визначити свою
логіку, коли наш клас буде більш продуктивним.

13. В чому різниця між інтерфейсами IComparer та IComplarable? Для чого вони
призначені? В яких випадках варто використовувати кожний із них?
IComplarable визначає узагальнений типовий метод порівняння, який реалізує
тип класу або клас для замовлення або сортування його екземплярів
CompareTo() порівнює поточний екземпляр з іншим об'єктом того ж типу і повертає
ціле число, яке вказує на те, чи перебуває даний екземпляр, випливає або
відбувається в тому ж положенні в порядку сортування, що й інший об'ект
IComparer виставляє метод, який порівнює да об’єкти
Compare() метод порівнює два об’єкти та повертає значення, яке вказує на те, чи є
він меншим, рівним або більшим, ніж інший.

14. В чому різниця між універсальними інтерфейсами IComplarer, IComparable та


узагальненими IComplarer, IComparable? Для чого призначені ці узагальнені
інтерфейси? В яких випадках варто використовувати кожний із них?
Для підвищення продуктивності (не треба витрачати час на упаковку і
розпаковування об'єкта) і підвищена безпеки типу використовують узагальнені
версії.

15. Для чого призначені інтерфейси IEnumerable, IEnumerator та IEnumerable<T>,


IEnumerator<T>?
Інтерфейс IEnumerable має метод, який повертає посилання на інший інтерфейс
- Нумератор. А інтерфейс IEnumerator визначає функціонал для перебору
внутрішніх об'єктів в контейнері.

You might also like