Структура
У цьому матеріалі ми коротко розповімо про таку мову програмування, як C#, її типові сфери використання та деякі особливості, серед яких трохи зупинимось на класах та використанні делегатів.
Коротко про мову C#, c# класи і делегати у ній
C# (вимовляється «сі шарп») — це без перебільшення одна з найпоширеніших мов програмування у світі з широким спектром сфер використання, серед яких:
- розробка десктопних застосунків для всіх актуальних оперативних систем (Microsoft Windows, Apple macOS, та GNU/Linux);
- створення мобільних застосунків для платформ iOS та Android за допомогою фреймворків Xamarin та .NET Core;
- розробка різноманітних веб та хмарних додатків, в тому числі на базі платформи ASP.NET;
- створення ігор на усіх платформах, включаючи PC (Windows), Xbox, PlayStation та інші;
- створення алгоритмів машинного навчання та інших задач штучного інтелекту, що зараз у всіх на слуху.
І це лише декілька прикладів застосування C#, бо ця мова має багато функціональних можливостей та високу швидкодію, що дозволяє використовувати її в найрізноманітніших галузях. Тим, хто вагається, чи слід вивчати саме цю мову, можуть бути цікаві деякі її базові особливості, наприклад:
- Об’єктноорієнтований підхід: C# побудована на принципах об’єктноорієнтованого програмування, що дозволяє з легкістю розширювати та знову використовувати код, який вже існує. Класи, об’єкти, наслідування, делегати, поліморфізм та інші принципи ООП значно спрощують створення складних програм, які до того ж легко розширювати.
- Строга типізація: C# має строгу типізацію, що дозволяє компілятору перевіряти правильність типів даних під час компіляції. Шляхом цього можна уникнути багатьох помилок, пов’язаних з неправильними типами даних. Також наявний механізм обробки винятків, що дозволяє опрацьовувати помилки під час виконання програми. Це дозволяє програмі продовжувати роботу навіть після виникнення похибки.
- Автоматичне управління пам’яттю: C# має систему автоматичного управління пам’яттю. Це дозволяє програмісту не відволікатися на очищення пам’яті після виконання операцій з об’єктами, де більшість помилок пов’язані з пам’яттю.
- Інтеграція з LINQ (Language Integrated Query): C# підтримує мову запитів LINQ, що дозволяє виконувати операції з даними безпосередньо в коді програми. Інтеграція C# з LINQ дозволяє використовувати замість, скажімо, SQL, мову запитів LINQ для вибору, фільтрації та маніпулювання даними з баз даних напряму, без потреби використовувати зайві конструкції коду.
На цьому завершимо нуднуватий вікіподібний аперитив для широкого загалу і перейдемо до основних страв. Вони будуть цікаві більш просунутій аудиторії, що вивчає або роздумує, чи треба вивчати C#.
Базова інформація про класи та делегати
Почнемо з класів. В першу чергу треба зазначити, що у C# клас — це шаблон для створення об’єктів, що містить поля (змінні) та методи (функції), які виконують операції над цими полями. Класи дозволяють використовувати об’єктноорієнтований підхід до програмування.
Клас в C# може складатися з таких елементів, як:
- Поля (fields) — змінні, що зберігають стан об’єкта.
- Методи (methods) — функції, що виконують операції над полями класу.
- Конструктори (constructors) — спеціальні методи, що використовуються для створення нового об’єкта.
- Властивості (properties) — спеціальні методи, що дозволяють зчитувати та записувати значення поля класу.
- Індексатори (indexers) — спеціальні методи, що дозволяють об’єкту поводитися як масив.
- Події (events) — механізм, що дозволяє об’єкту відстежувати події та реагувати на них.
Основна мета класів — забезпечення відділення та ізоляції даних та функціоналу. Це дає змогу ефективніше використовувати, підтримувати та доповнювати код. Класи в C# можуть бути наслідувані, і таким чином створювати складніші структури об’єктів.
Делегати в C# — це типи, що посилаються на метод. До особливостей делегатів можна віднести наступне:
- Посилання на метод: делегати дозволяють зберігати посилання на метод, який можна пізніше викликати в коді програми.
- Типізованість: делегати є типізованими, що дозволяє компілятору перевірити правильність типів при використанні делегатів.
- Можливість передачі в метод: делегати можуть передаватися як аргументи в методи, що дозволяє розширювати функціональність програми.
- Можливість комбінування: делегати можуть бути комбіновані за допомогою операторів “+” та “-“, що дозволяє додавати або видаляти методи, на які посилається делегат.
- Анонімність методів: C# підтримує анонімні методи, які можуть бути передані як делегати. Це дозволяє використовувати замикання та лямбда-вирази.
- Підтримка подій: в C# делегати підтримують події, що дозволяє створювати механізм підписки на них та виклику методів, які пов’язані з подією.
В цілому делегати дозволяють передавати методи як параметри, комбінувати їх, створювати анонімні методи та підтримувати події, а також забезпечують модульність та гнучкість програми.
Приклади базових делегатів в C#
Action — делегат, який не повертає значення, але приймає параметри. Він використовується, коли потрібно викликати метод, який не повертає жодного значення, але може виконувати певні дії.
Делегат Action означає деяку дію, яка нічого не повертає, тобто має тип void:
public delegate void Action()
public delegate void Action<in T>(T obj)
Цей делегат має кілька перевантажених версій, кожна з яких може прийняти різну кількість параметрів: від Action<in T1> до Action<in T1, in T2,…in T16>. Тобто йому можна передати до 16 параметрів.
Зазвичай цей делегат є параметром методу та передбачає виклик певної дії у відповідь на попередні результати. Наприклад:
DoOperation(10, 6, Add); // 10 + 6 = 16
DoOperation(10, 6, Multiply); // 10 * 6 = 60
void DoOperation(int a, int b, Action<int, int> op) => op(a, b);
void Add(int x, int y) => Console.WriteLine($”{x} + {y} = {x + y}”);
void Multiply(int x, int y) => Console.WriteLine($”{x} * {y} = {x * y}”);
Func — делегат, який приймає один або більше параметрів і повертає певне значення. Він використовується, коли потрібно викликати метод, який повертає результат після виконання.
Func повертає результат дії та може приймати параметри. Він також має різні форми: від Func<out T>(), в якому T — тип значення, яке повертається до Func<in T1, in T2,…in T16, out TResult>(), тобто він теж може приймати до 16 параметрів.
TResult Func<out TResult>()
TResult Func<in T, out TResult>(T arg)
TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2)
TResult Func<in T1, in T2, in T3, out TResult>(T1 arg1, T2 arg2, T3 arg3)
TResult Func<in T1, in T2, in T3, in T4, out TResult>(T1 arg1, T2 arg2, T3 arg3, T4 arg4)
//…………………………………….
Цей делегат також часто використовується як параметр у методах:
int result1 = DoOperation(6, DoubleNumber); // 12
Console.WriteLine(result1);
int result2 = DoOperation(6, SquareNumber); // 36
Console.WriteLine(result2);
int DoOperation(int n, Func<int, int> operation) => operation(n);
int DoubleNumber(int n) => 2 * n;
int SquareNumber(int n) => n * n;
Метод DoOperation() як параметр приймає делегат Func<int, int>, а саме посилання на метод, що приймає число int та повертає значення такого ж типу int.
При першому виклику методу DoOperation() йому передається посилання на метод DoubleNumber, який збільшує число вдвічі. У другому ж випадку передається метод SquareNumber, який повертає значення переданого числа в квадраті.
Predicate — делегат, який приймає один параметр і повертає логічне значення типу bool. Він використовується, коли потрібно викликати метод, який перевіряє, чи відповідає певний об’єкт заданому критерію.
Делегат Predicate приймає лише один параметр і повертає значення типу bool:
delegate bool Predicate<in T>(T obj);
Даний предикат використовується для порівняння деякого об’єкта T із заданою умовою. Як результат повертається значення true, якщо умова виконується, і false, якщо не виконується:
Predicate<int> isPositive = (int x) => x > 0;
Console.WriteLine(isPositive(20));
Console.WriteLine(isPositive(-20));
В даному прикладі повертається true або false в залежності від того, чи число більше нуля або ні.
Висновок
В статті ми розглянули, що таке мова C#, класи, делегати та як з ними працювати. І це навіть не вся вершина айсберга. У мові C# є багато інших типів делегатів. Але розглянуті три делегати є найбільш поширеними і найчастіше використовуються на практиці.