Процедурное и объектно-ориентированное программирование
До появления классов в языках вроде языка C понятия класса не существовало. Программирование без классов и объектов, характерное для C, называется процедурным программированием.
Процедурное программирование: программа представляет собой последовательность инструкций, основной фокус — оптимизация шагов выполнения.
С появлением классов становится возможным объектно-ориентированное программирование
Объектно-ориентированное программирование: программа состоит из набора инкапсулированных классов. Основная идея — объединить данные и функции, работающие с этими данными в логически связанные блоки, такими блоками являются классы (class).
Определение класса
Класс — это структура данных, содержащая хранимые данные и исполняемый код. В нём выделяют две группы членов:
- Члены данных (Data Members) хранят атрибуты объекта: поля (Fields), константы (Constants)
- Функциональные члены (Function Members) реализуют поведение объекта: методы, свойства, конструкторы, деструкторы, операторы, индексаторы, события
Класс — это набор инкапсулированных логически связанных данных и функций, предназначенный для моделирования сущностей реального или абстрактного мира.
Проще говоря, класс — это структура данных, состоящая из данных и функций. Из класса можно создавать объекты, через объекты обращаться к данным и членам, доступ к данным и членам возможен и изнутри самого класса.
Объявление класса
Ключевое слово class определяет только шаблон класса, оно не создаёт экземпляры объектов. Шаблон состоит из трёх частей: имя класса, члены класса, характеристики класса.
Синтаксис
class ИмяКласса
{
// объявление членов (поля, методы, порядок не регламентирован)
}Code language: JavaScript (javascript)
Объявление класса часто называют определением класса (class definition)
class Program
{
static void Main(string[] args)
{
AddCalculator addCalculator = new AddCalculator();
SubCalculator subCalculator = new SubCalculator();
}
}
class AddCalculator
{
public int A { get; set; }
public int B { get; set; }
public int Add()
{
return A + B;
}
}
class SubCalculator
{
public int A { get; set; }
public int B { get; set; }
public int Subtract()
{
return A - B;
}
}Code language: JavaScript (javascript)
В примере выше объявлены два класса: один для сложения, второй для вычитания. В главной функции Main основного приложения мы создаём экземпляры этих классов для работы.
Материал взят с сайта foxdevelop.com
Объявления классов не обязательно располагать сверху вниз. Вы можете описать классы ниже по коду, а вызывать их в расположенной выше функции Main. Класс — лишь шаблон, чертёж. Код выполняется не последовательно сверху вниз, запуск начинается с функции Main, и при необходимости программа обращается к нужному шаблону класса.

Члены класса
Поля (Fields)
Поле — это переменная, принадлежащая классу. Оно может быть встроенного или пользовательского типа, поддерживает чтение и запись данных.
Тип ИмяПоля;
class MyClass
{
int MyField; // поле MyField типа int
}Code language: JavaScript (javascript)
Важное отличие от C/C++: в C# глобальные переменные отсутствуют. Все поля должны объявляться внутри типа (класса или структуры).
Правила инициализации полей
(1) Неявная инициализация (без явного присваивания)
Компилятор автоматически присваивает значение по умолчанию для каждого типа; значения по умолчанию отличаются для разных типов.
int F1; // по умолчанию 0
string F2; // по умолчанию nullCode language: JavaScript (javascript)
В таблице ниже представлено соответствие типов C# и значений по умолчанию для полей. Локальные переменные программист обязан инициализировать самостоятельно.
Простые типы значений
| Тип данных | Значение по умолчанию | Описание |
|---|---|---|
sbyte | 0 | Знаковое 8-битное целое |
byte | 0 | Беззнаковое 8-битное целое |
short | 0 | Знаковое 16-битное целое |
ushort | 0 | Беззнаковое 16-битное целое |
int | 0 | Знаковое 32-битное целое |
uint | 0 | Беззнаковое 32-битное целое |
long | 0L | Знаковое 64-битное целое |
ulong | 0UL | Беззнаковое 64-битное целое |
float | 0.0f | Одинарная точность, плавающая запятая |
double | 0.0d | Двойная точность, плавающая запятая |
decimal | 0.0m | Высокоточное десятичное число |
char | '\0' (нулевой символ, ASCII 0) | Один символ |
bool | false | Логический тип |
Перечисление Enum | Элемент перечисления, соответствующий базовому целому 0 | Перечисления основаны на целых числах, по умолчанию равны нулю |
Структура struct | Все поля получают собственные значения по умолчанию | Пользовательский тип значения, обнуляется целиком |
Ссылочные типы
Для всех ссылочных типов значение по умолчанию — null. Это означает, что переменная не ссылается ни на один объект в куче памяти.
Другими словами, переменная не хранит никакой адрес памяти. Вспомните схему памяти, рассмотренную ранее: ссылочные типы хранят адреса вида 000001 01010, указывающие на кучу. При значении null никакой действительный адрес не сохраняется.
| Категория типа | Примеры типов | Значение по умолчанию |
|---|---|---|
| Встроенные ссылочные типы | string, object | null |
Пользовательский класс class | Person Student | null |
| Массивы (любая размерность) | int[], string[,] | null |
| Делегаты / События | Action, Func, пользовательский delegate | null |
Интерфейс interface | Любая переменная интерфейса | null |
Примеры
string str; // по умолчанию null
Student jason; // пользовательский класс, по умолчанию null
int[] arr; // массив, по умолчанию null
Action callback; // делегат, по умолчанию nullCode language: JavaScript (javascript)
Типы, допускающие значение null (Nullable / T?)
Если после базового типа данных поставить знак вопроса ?, получится новый тип, который может не содержать значения. Рассмотрим пример: переменная int age; без присваивания равна 0. Если нужно явно указать, что значения нет, пишут int? age2;. Переменная age2 является допускающей null, ей можно присвоить null: int? age2 = null;
Тип, допускающий null, — обёрнутый ValueType, его значение по умолчанию null, что означает «нет действительного значения».
| Синтаксис объявления | Значение по умолчанию |
|---|---|
int? num | null |
bool? flag | null |
decimal? price | null |
class Test
{
int a; // автоматически = 0
string b; // автоматически = null
bool c; // автоматически = false
}Code language: JavaScript (javascript)
(2) Явная инициализация
При объявлении переменной присваиваем значение через =. Присваиваемое значение должно быть определено во время компиляции; нельзя использовать случайные значения или данные, введённые пользователем.
int days = 25;
string word = "foxdevelop";Code language: JavaScript (javascript)
(3) Сокращённое объявление нескольких полей одного типа
Переменные одного типа можно объявлять списком через запятую. Смешивать разные типы в одной строке запрещено
int player, blood = 25;
string title, subTitle = "hi welcome to foxdevelop.com";Code language: JavaScript (javascript)
Методы (Methods)
Определение метода
Метод — это именованный многократно используемый блок исполняемого кода, аналог член-функции в C++. После вызова выполняется внутренний код, после чего управление возвращается в точку вызова. Методы делятся на два вида: с возвращаемым значением и без возвращаемого значения.
Четыре составляющие метода
- Тип возвращаемого значения: при отсутствии возврата указывают
void - Имя метода
- Список параметров: скобки
()обязательны даже при отсутствии параметров - Тело метода: исполняемый код обрамляется
{}
class Program
{
static void Main(string[] args)
{
Robot robot = new Robot();
robot.SayHello();
}
}
class Robot
{
public void SayHello()
{
Console.WriteLine("Hello everyone");
Console.WriteLine("Welcome to visit foxdevelop.com");
}
}Code language: JavaScript (javascript)
Модификатор public перед public void SayHello() позволяет обращаться к функции снаружи класса по схеме имяОбъекта.ИмяФункции. Если модификатор public не указан, по умолчанию действует private. Закрытые (private) функции вызываются только внутри тела класса; извне, даже через переменную объекта robot, доступ к ним невозможен.

Создание переменных класса и экземпляров
1. Основные свойства ссылочных типов
Классы относятся к ссылочным типам. Память разделена на две области:
- Стек (Stack): хранит ссылочные переменные (указатели на адреса памяти)
- Куча (Heap): хранит реальные данные объекта
2. Пошаговое создание объекта
1 Только объявление ссылочной переменной (выделяется память в стеке, объекта в куче нет)
Robot robot;
// выделяется место под ссылку в стеке, значение не определено, объект в куче отсутствует
Code language: JavaScript (javascript)

2 Выделение памяти в куче оператором new
new ИмяТипа();Code language: JavaScript (javascript)
- Выделяет память в куче и автоматически инициализирует все поля значениями по умолчанию
- Возвращает адрес ссылки на объект в куче и присваивает его переменной стека
robot = new Robot();
Code language: JavaScript (javascript)

class Program
{
static void Main(string[] args)
{
Robot robot;
robot = new Robot();
}
}
class Robot
{
void SayHello()
{
Console.WriteLine("Hello everyone");
Console.WriteLine("Welcome to visit foxdevelop.com");
}
}Code language: JavaScript (javascript)
3. Объявление и создание экземпляра в одной строке
Robot robot = new Robot();Code language: JavaScript (javascript)
class Program
{
static void Main(string[] args)
{
Robot robot = new Robot();
}
}Code language: JavaScript (javascript)
Определение класса