- •Розділ 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. Специфікатори формату для рядків с#
5.3.4. Вихідні параметри
Досить часто виникає необхідність в методах, які формують декілька величин, наприклад, якщо в методі створюються об'єкти або ініціалізуються ресурси. В цьому випадку стає незручним обмеження параметрів-посилань: необхідність надання значення аргументу до виклику методу. Це обмеження знімає специфікатор out. Параметру, що має цей специфікатор, має бути обов'язково привласнене значення усередині методу, компілятор за цим стежить. Зате в коді можна обмежитися описом змінною без ініціалізації.
Змінимо опис другого параметра в лістингу 5.4 так, щоб він став вихідним (лістинг 5.5).
При виклику методу перед відповідним параметром теж указується ключове слово out.
Лістинг 5.5. Вихідні параметри
using System;
namespace ConsoleApplicationl
{
class Class1
{
static void P( int a, out int b )
{
a = 44; b = 33;
Console.WriteLine( "усередині методу {0} {1}", a, b );
}
static void Main( )
{
int a = 2, b;
P( a, out b );
Console.WriteLine( "після виклику {0} {1}", a, b );
}
}
}
Результат роботи цієї програми:
усередині методу 44 33
після виклику 2 33
Рекомендується, в списку параметрів записуйте спочатку всі вхідні параметри, потім всі посилання і вихідні параметри. Давайте параметрам імена, за якими можна отримати уявлення про їх призначення.
5.4. Ключове слово this
Кожен об'єкт містить свій екземпляр полів класу. Методи знаходяться в пам'яті в єдиному екземплярі і використовуються всіма об'єктами спільно, тому необхідно забезпечити роботу методів нестатичних екземплярів з полями саме того об'єкту, для якого вони були викликані. Для цього в будь-який нестатичний метод автоматично передається прихований параметр this, в якому зберігається посилання на екземпляр, що викликав функцію.
У явному вигляді параметр this застосовується для того, щоб повернути з методу посилання на об'єкт, що викликав, а також для ідентифікації поля у випадку, якщо його ім'я збігається з ім'ям параметра методу, наприклад:
class Demo
{
double у;
public Demo T( ) // метод повертає посилання на екземпляр
{
return this;
}
public void Sety ( double у )
{
this.y = у; // полю у привласнюється значення параметра
}
}
5.5. Конструктори
Конструктор призначений для ініціалізації об'єкту. Він викликається автоматично при створенні об'єкту класу за допомогою операції new. Ім'я конструктора збігається з ім'ям класу. Нижче перераховані властивості конструкторів:
Конструктор не повертає значення, навіть типу void.
Клас може мати декілька конструкторів з різними параметрами для різних видів ініціалізації.
Якщо програміст не вказав жодного конструктора або якісь поля не ініціалізовані, полям значущих типів привласнюється нуль, полям посилальних типів - значення null.
Конструктор, що викликається без параметрів, називається конструктором за умовчанням.
До цих пір ми задавали початкові значення полів класу при описі класу (лістинг 5.1). Це зручно у тому випадку, коли для всіх екземплярів класу початкові значення деякого поля однакові. Якщо ж при створенні об'єктів потрібно привласнювати полю різні значення, це слід робити в конструкторі. У лістингу 5.6 в клас Demo доданий конструктор, а поля зроблені закритими (непотрібні в даний момент елементи відсутні). У програмі створюються два об'єкти з різними значеннями полів.
Лістинг 5.6. Клас з конструктором
usingSystem;
namespace ConsoleApplicationl
{
class Demo
{
public int a = 1 ;
public const double с = 1.66;
double y;
public Demo( int a, double y ) // конструктор з параметрами
{
this.a = a;
this.y = y;
}
public double Gety( ) // метод отримання поля у
{
return y;
}
}
class Classl
{
static void Main( )
{
Demoa=newDemo( 300, 0.002); //виклик конструктора
Console.WriteLine (a.Gety( )); // результат: 0,002
Demo b = new Demo(1,5.71 ); // виклик конструктора
Console.WriteLine( b.Gety( ) ); // результат: 5,71
}
}
}
Часто буває зручно задати в класі декілька конструкторів, щоб забезпечити можливість ініціалізації об'єктів різними способами. Приклад:
class Demo
{
public Demo( int a ) // конструктор 1
{
this.a = a;
this.у = 0.002;
}
public Demo( double у ) // конструктор 2
{
this.a = 1;
this.у = у;
}
…
}
…
Demo x = new Demo( 300 ); // виклик конструктора 1
Demo у = new Demo( 5.71 ); // виклик конструктора 2
Всі конструктори повинні мати різні сигнатури.
Якщо один з конструкторів виконує які-небудь дії, а інший повинен робити те ж саме плюс ще що-небудь, зручно викликати перший конструктор з другого. Для цього використовується вже відоме вам ключове слово this в іншому контексті, наприклад:
class Demo
{
public Demo( int a ) // конструктор 1
{
this.a = a;
}
public Demo( int a, double у ) : this(a) // виклик конструктора 1
{
this.у = у;
}
…
}
Конструкція, що знаходиться після двокрапки, називається ініціалізатором, тобто тим кодом, який виконується до початку виконання тіла конструктора.
Як ви пам'ятаєте, всі класи в С# мають загального предка - клас object. Конструктор будь-якого класу, якщо не вказаний ініціалізатор, автоматично викликає конструктор свого предка. Це можна зробити і явним чином за допомогою ключового слова base, що позначає конструктор базового класу. Таким чином, перший конструктор з попереднього прикладу можна записати і так:
public Demo( int а ) : base( ) // конструктор 1
{
this.а = а;
}
Конструктор базового класу викликається явним чином в тих випадках, коли йому потрібно передати параметри.
До цих пір мова йшла про “звичайні ” конструктори, або конструктори екземпляра. Існує другий тип конструкторів - статичні конструктори, або конструктори класу. Конструктор екземпляра ініціалізував дані екземпляра, конструктор класу - дані класу.
У класі, що складається тільки із статичних елементів (полів і констант), описувати статичний конструктор не обов'язково, початкові значення полів зручніше задати при їх описі.
В лістингу 5.7 приведений приклад статичного класу.
Лістинг 5.7. Статичний клас
using System;
namespace ConsoleApplicationl
{
static class D
{
static int a = 200;
static double b = 0.002;
public static void Print ( )
{
Console.WriteLine("a="+a);
Console.WriteLine("b="+b);
}
}
class Classl
{
static void Main( )
{
D.Print( );
}
}
}
Як приклад, на якому демонструватиметься робота різними елементами класу, створимо клас Monster, моделюючий персонаж комп'ютерної гри. Для цього потрібно задати його властивості (наприклад, кількість щупальців, силу або наявність гранатомета) і поведінку. Опис класу Monster приводиться на лістингу 5.8.
Лістинг 5.8. Клас Monster
using System;
namespace ConsoleApplication1
{
class Monster
{
public Monster( )
{
this.name = "Noname";
this.health = 100;
this.ammo = 100;
}
public Monster(string name) : this( )
{
this.name = name;
}
public Monster( int health, int ammo, string name )
{
this.name = name;
this.health = health;
this.ammo = ammo;
}
public string GetName( )
{
return name;
}
public int GetHealth( )
{
return health;
}
public int GetAmmo( )
{
return ammo;
}
public void Passport( )
{
Console.WriteLine( "Monster {0} \t health = {1} ammo = {2}",
name, health, ammo );
}
string name; // закриті поля
int health, ammo;
}
class Classl
{
static void Main()
{
Monster X = new Monster( );
X.Passport( );
Monster Vasia = new Monster("Vasia");
Vasia.Passport( );
Monster Masha = new Monster(200, 200, "Masha" );
Masha.Passport( );
}
}
}
Результат роботи програми:
Monster Noname health = 100 ammo = 100
Monster Vasia health = 100 ammo = 100
Monster Masha health = 200 ammo = 200
У класі три закриті поля (name, health і ammo), чотири методи (Getname, Gethealth, Getammo і Passport) і три конструктори.