- •Розділ 1. Основи платформи .Net
- •1.1. Основи платформи .Net
- •1.2. Загальні відомості об'єктно-орієнтованого програмування
- •1.3. Середовище Visual Studio .Net
- •1.4 Консольні додатки
- •Розділ 2. Основні поняття мови
- •2.1. Склад мови
- •2.1.1 Алфавіт і лексеми
- •2.1.2. Ідентифікатори і ключові слова
- •2.1.3. Знаки операцій і роздільники
- •2.1.4. Літерали
- •Константи в с#
- •Суфікси цілих і дійсних констант
- •Управляючі послідовності у с#
- •2.1.5. Коментарі
- •2.2. Типи даних
- •2.2.1. Класифікація типів
- •2.2.2. Типи літералів
- •2.2.3. Типи-значення і посилальні типи
- •2.2.4. Упаковка і розпаковування
- •2.3. Рекомендації по програмуванню
- •Розділ 3. Змінні, іменовані константи, операції і вирази
- •3.1. Змінні і іменовані константи
- •3.2. Операції і вирази
- •3.2.1. Перетворення вбудованих арифметичних типів-значень
- •3.2.2. Введення у виключення
- •3.2.3. Основні операції с#
- •Операнд_1 ? операнд_2 : операнд_3.
- •3.3. Лінійні програми (програмування лінійних обчислювальних процесів)
- •3.3.1. Просте введення-виведення даних
- •3.3.2. Математичні функції - клас Math
- •Розділ 4. Оператори
- •4.1. Вирази, блоки
- •4.2. Оператори розгалуження
- •4.2.1. Умовний оператор if
- •4.2.1. Умовний оператор switch
- •4.3. Оператори циклу
- •4.3.1. Цикл з передумовою while
- •4.3.2. Цикл з постумовою do
- •4.3.3. Цикл з параметром for
- •For ( ініціалізація; вираз; модифікації ) оператор;
- •4.3.4. Цикл перебору foreach
- •4.3.5. Рекомендації по вибору оператора циклу
- •4.4. Обробка виняткових ситуацій
- •4.4.1. Оператор try
- •Try блок [ блоки catch ] [ блок finally ]
- •4.4.2. Оператор throw
- •Throw [ вираз ];
- •4.4.3. Клас Exception
- •4.4.4. Оператори checked и unchecked
- •4.5. Рекомендації по програмуванню
- •Розділ 5. Класи: основні поняття
- •5.1. Привласнення і порівняння об'єктів
- •5.2. Дані: поля і константи
- •5.3. Методи
- •5.3.1. Параметри методів
- •5.3.2. Параметри-значення
- •5.3.3. Параметри-посилання
- •5.3.4. Вихідні параметри
- •5.4. Ключове слово this
- •5.5. Конструктори
- •5.6. Властивості
- •[ Атрибути ] [ специфікатори ] тип ім’я_властивості
- •[ Get код_доступа ] [ set код_доступа ]
- •5.7. Рекомендації по програмуванню
- •Розділ 6. Масиви і рядки
- •6.1. Одновимірні масиви
- •6.2. Прямокутні масиви
- •6.3. Ступінчасті масиви
- •6.4. Клас System.Array
- •6.5. Клас Random
- •6.6. Оператор foreach
- •6.7. Масиви об’єктів
- •6.8. Символи і рядки
- •6.8.1. Символи
- •6.8.2. Масиви символів
- •6.8.3. Рядки типу string
- •6.8.4. Форматування рядків
- •6.8.5. Рядки типу StringBuilder
- •6.9. Рекомендації з програмування
- •Розділ 7. Класи: подробиці
- •7.1. Перевантаження методів
- •7.2. Рекурсивні методи
- •7.3. Методи із змінною кількістю аргументів
- •7.4. Метод Main
- •7.5. Індексатори
- •7.6. Операції класу
- •7.6.1. Унарні операції
- •7.6.2. Бінарні операції
- •7.6.3. Операції перетворення типу
- •7.7. Деструктор
- •7.8. Вкладені типи
- •7.9. Рекомендації по програмуванню
- •Розділ 8. Ієрархії класів
- •8.1. Спадкоємство
- •8.2. Віртуальні методи
- •8.3. Абстрактні класи
- •8.4. Безплідні класи
- •8.5. Клас object
- •8.6. Рекомендації по програмуванню
- •Розділ 9. Інтерфейси і структурні типи
- •9.1. Синтаксис інтерфейсу
- •9.2. Реалізація інтерфейсу
- •9.3. Робота з об'єктами через інтерфейси. Операції is і as
- •9.4. Інтерфейси і спадкоємство
- •9.5. Стандартні інтерфейси .Net
- •9.5.1. Порівняння об'єктів (інтерфейс iComparable)
- •9.5.2 Сортування по різних критеріях (інтерфейс iComparer)
- •9.5.3 Перевантаження операцій відношення
- •9.5.4. Клонування об'єктів (інтерфейс iСloneable)
- •9.5.5. Перебір об'єктів (інтерфейс iEnumerable) і ітератори
- •9.6. Структури
- •9.7. Перелічення
- •9.7.1 Операції з переліченнями
- •9.7.2. Базовий клас System.Enum
- •9.8. Рекомендації по програмуванню
- •Розділ 10. Делегати, події і потоки виконання
- •10.1. Делегати
- •10.1.1. Опис делегатів
- •10.1.2. Використання делегатів
- •10.1.3. Патерн “спостерігач”
- •10.1.4. Операції
- •10.1.5. Передача делегатів в методи
- •10.1.6. Обробка виключень при виклику делегатів
- •10.3. Багатопотокові додатки
- •10.3.1. Клас Thread
- •Lock ( вираз ) блок_операторів
- •10.3.2. Асинхронні делегати
- •10.4. Рекомендації по програмуванню
- •Розділ 11. Робота з файлами
- •11.1. Потоки байтів
- •11.2. Асинхронне уведення-виведення
- •11.3. Потоки символів
- •11.4. Двійкові потоки
- •11.5. Консольне уведення-виведення
- •11.6. Робота з каталогами і файлами
- •11.7. Збереження об'єктів (серіалізація)
- •11.8. Рекомендації по програмуванню
- •Розділ 12. Збірки, бібліотеки, атрибути, директиви
- •12.2. Створення бібліотеки
- •12.3. Рефлексія
- •12.4. Атрибути
- •12.5. Простір імен
- •12.6. Директиви препроцесора
- •# Константний_вираз
- •[ #Elif константний_вираз
- •[ #Elif константний_вираз
- •Розділ 13. Структури даних, колекції і класи-прототипи
- •13.1. Абстрактні структури даних
- •13.2. Простір імен System.Collections
- •13.3. Клас ArrayList
- •13.4. Класи-прототипи
- •13.5. Створення класу-прототипу
- •13.6. Узагальнені методи
- •13.7. Часткові типи
- •13.8. Типи, що обнуляються
- •13.9. Рекомендації по програмуванню
- •Розділ 14. Додаткові засоби с#
- •14.1. Небезпечний код
- •Unsafe блок
- •14.1.1. Синтаксис вказівок
- •14.1.2. Перетворення та ініціалізація вказівок
- •14.1.3. Операції з вказівками
- •14.2. Регулярні вирази
- •14.2.1. Метасимволи
- •14.2.2. Класи бібліотеки .Net для роботи з регулярними виразами
- •14.3. Документування у форматі xml
- •Лабораторні роботи
- •Лабораторна робота 5. Одновимірні масиви
- •Лабораторна робота 6. Двовимірні масиви
- •Лабораторна робота 7. Рядки
- •Лабораторна робота 8. Класи і операції
- •Лабораторна робота 9. Спадкоємство
- •Лабораторна робота 10. Структури
- •Лабораторна робота 11. Інтерфейси і параметризовані колекції
- •Список літератури
- •Додатки Додаток 1. Специфікатори формату для рядків с#
10.1.4. Операції
Делегати можна порівнювати на рівність і нерівність. Два делегати рівні, якщо вони обидва не містять посилань на методи або якщо вони містять посилання на одні і ті ж методи в одному і тому ж порядку. Порівнювати можна навіть делегати різних типів за умови, що вони мають один і той же тип повертаємого значення і однакові списки параметрів.
Делегати, які розрізняються тільки іменами, вважаються за тих, які мають різні типи.
З делегатами одного типу можна виконувати операції простого і складного привласнення, наприклад:
Del d1 = new Del (o1.Do): // o1.Do
Del d2 = new Del (o2.Do); // o2.Do
Del d3 = d1 + d2; // ol.Do і o2.Do
d3 += d1; // ol.Do. o2.Do і ol.Do
d3 -= d2; // o1.Do і ol.Do
Ці операції можуть знадобитися, наприклад, в тому випадку, якщо в різних обставинах потрібно викликати різні набори і комбінації наборів методів.
Делегат, як і рядок string, є незмінним типом даних, тому при будь-якій зміні створюється новий екземпляр, а старий згодом видаляється складальником сміття.
10.1.5. Передача делегатів в методи
Оскільки делегат є класом, його можна передавати в методи як параметр. Цим забезпечується функціональна параметризація: у метод можна передавати не тільки різні дані, але і різні функції їх обробки. Функціональна параметризація застосовується для створення універсальних методів і забезпечення можливості зворотного виклику.
Як універсальний метод можна привести метод виведення таблиці значень функції. У метод передається діапазон значень аргументу, крок його зміни і вид обчислюваної функції. Цей приклад наводиться далі.
Зворотним викликом (callback) є виклик функції, яка передається в іншу функцію як параметр. Розглянемо рис. 10.1. Допустимо, в бібліотеці описана функція А, параметром якої є ім'я іншої функції. У коді описується функція з необхідною сигнатурою (В) і передається у функцію А. Виконання функції А приводить до виклику В, тобто управління передається з бібліотечної функції назад в код.
Рис. 10.1. Механізм зворотного виклику
Механізм зворотного виклику широко використовується в програмуванні. Наприклад, він реалізується в багатьох стандартних функціях Windows.
Приклад передачі делегата як параметр приведений в лістингу 10.3. Програма виводить таблицю значень функції на заданому інтервалі з кроком, рівним одиниці.
Лістинг 10.3. Передача делегата через список параметрів
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace examp67
{
public delegate double Fun( double x ); // оголошення делегата
class Classl
{
public static void Table (Fun F, double x, double b )
{
Console.WriteLine( " X Y " );
while (x <= b)
{
Console.WriteLine("| {0,8:0.000} | {1,8:0.000}", x, F(x));
x += 1;
}
Console.WriteLine( " ....................." );
}
public static double Simple(double x)
{
return 1;
}
static void Main(string[] args)
{
Console.WriteLine("Таблиця функції Sin");
Table(new Fun( Math.Sin), -2, 2 );
Console.WriteLine(" Таблиця функції Simple " );
Table( new Fun(Simple), 0, 3 );
}
}
}
Результат роботи програми:
Таблиця функції Sin
-------X ------- Y --------
I -2.000 I -0,909 I
I -1.000 I -0,841 I
I 0.000 I 0,000 I
I 1,000 I 0.841 I
I 2,000 I 0,909 I
-------------------------------
Таблиця функції Simple
-------X ------- Y -------
I 0.000 I 1,000 I
I 1.000 I 1,000 I
I 2.000 I 1,000 I
I 3.000 I 1,000 I
-------------------------------
Має місце спрощений синтаксис для делегатів. Перше спрощення полягає в тому, що в більшості випадків явним чином створювати екземпляр делегата не потрібно, оскільки він створюється автоматично по контексту. Друге спрощення полягає в можливості створення так званих анонімних методів - фрагментів коду, що описуються безпосередньо в тому місці, де використовується делегат. У лістингу 10.4 використано обидва спрощення для реалізації тих же дій, що і лістингу 10.3.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace examp68
{
public delegate double Fun(double x); // об’ява делегата
class Classl
{
public static void Table(Fun F, double x, double b)
{
Console.WriteLine(" X Y ");
while (x <= b)
{
Console.WriteLine("| {0,8:0.000} | {1,8:0.000}", x, F(x));
x += 1;
}
Console.WriteLine(" .....................");
}
public static double Simple(double x)
{
return 1;
}
static void Main(string[] args)
{
Console.WriteLine(" Таблиця функції Sin ");
Table(Math.Sin, -2, 2);
Console.WriteLine(" Таблиця функції Simple ");
Table(delegate(double x){return 1;}, 0, 3);
}
}
}
У першому випадку екземпляр делегата, відповідного функції Sin, створюється автоматично. Щоб це могло відбутися, список параметрів і тип повертаємого значення функції мають бути сумісні з делегатом. У другому випадку не потрібно оформляти фрагмент коду у вигляді окремої функції Simple, як це було зроблено в попередньому лістингу, - код функції оформляється як анонімний метод і вбудовується прямо в місце передачі.
Альтернативою використанню делегатів як параметрів є віртуальні методи. Метод виведення значень функції у вигляді таблиці можна реалізувати за допомогою абстрактного базового класу. Він містить два методи: метод виведення таблиці і абстрактний метод, для обчислення функції. Для виведення таблиці конкретної функції необхідно створити похідний клас, який перевизначає цей абстрактний метод. Реалізація методу виведення таблиці за допомогою спадкоємства і віртуальних методів приведена в лістингу 10.5.
Листинг 10.5. Альтернатива параметрам-делегатам
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace examp69
{
abstract class TableFun
{
public abstract double F(double x );
public void Table(double x, double b )
{
Console.WriteLine( " X Y " );
while ( x <= b )
{
Console.WriteLine(" {0,8:0.000} | {1,8:0.000} |", x, F(x));
x+=1;
}
Console.WriteLine( " ....................." );
}
}
class SimpleFun : TableFun
{
public override double F( double x ) {
return 1;
}
}
class SinFun : TableFun
{
public override double F( double x )
{
return Math.Sin(x);
}
}
class Classl
{
static void Main()
{
TableFun a = new SinFun();
Console.WriteLine(" Таблица функции Sin " );
a.Table(-2, 2 );
a = new SimpleFun();
Console.WriteLine(" Таблица функции Simple " );
a.Table(0,3);
}
}
}
Результат роботи цієї програми такий же, як і попередньої, але в даному випадку застосування делегатів переважно.