Основы языка C# для начинающих

Этот курс охватывает фундаментальные концепции языка C#, включая синтаксис, работу с данными и базовые алгоритмы. Студенты научатся создавать простые приложения и познакомятся с принципами объектно-ориентированного программирования.

1. Введение в платформу .NET и структура программы

Введение в платформу .NET и структура программы

Добро пожаловать в курс «Основы языка C# для начинающих»! Это первая статья, с которой начнется ваше путешествие в мир профессиональной разработки программного обеспечения. C# (произносится как «си-шарп») — это один из самых популярных, мощных и универсальных языков программирования в мире. На нем пишут всё: от небольших утилит для рабочего стола до масштабных веб-сервисов, мобильных приложений и даже современных видеоигр.

Но прежде чем мы напишем нашу первую строчку кода, важно понять фундамент, на котором стоит этот язык. C# не существует в вакууме; он неразрывно связан с платформой .NET.

Что такое C# и .NET? В чем разница?

Новички часто путают понятия «язык C#» и «платформа .NET». Давайте разберем это на простой аналогии.

Представьте, что вы хотите написать книгу.

* C# — это язык, на котором вы пишете (как русский или английский). Он определяет правила грамматики, синтаксис и то, как вы выражаете свои мысли. * .NET — это инфраструктура (издательство, типография, сеть книжных магазинов). Это огромный набор готовых инструментов, библиотек и сервисов, которые позволяют вашей «книге» (программе) быть напечатанной, доставленной читателю и прочитанной на разных устройствах.

Вы не можете запустить код C# сам по себе, просто написав текст в блокноте. Ему нужна среда для выполнения, и эту среду предоставляет .NET.

!Схема взаимодействия языка C#, платформы .NET и операционной системы

Из чего состоит .NET?

Платформа .NET состоит из двух главных компонентов, о которых вам нужно знать:

  • CLR (Common Language Runtime) — общеязыковая среда выполнения. Это «сердце» .NET. Именно CLR управляет вашей программой: выделяет память, обрабатывает ошибки, обеспечивает безопасность и, самое главное, переводит ваш код в команды, понятные процессору компьютера.
  • FCL (Framework Class Library) — библиотека классов фреймворка. Это гигантский набор готового кода, написанного за вас разработчиками Microsoft. Хотите работать с файлами? Есть готовый класс. Нужно отправить запрос в интернет? Есть класс. Хотите нарисовать окно? И для этого есть класс. Вам не нужно изобретать велосипед.
  • Как компьютер понимает ваш код?

    Компьютеры не понимают C#. Они понимают только машинный код (нули и единицы). Процесс превращения вашего текста на C# в работающую программу называется компиляцией. В мире .NET этот процесс происходит в два этапа, что делает его особенным.

    Этап 1: Компиляция в промежуточный язык (IL)

    Когда вы нажимаете кнопку «Собрать» (Build) в вашей среде разработки, компилятор C# проверяет ваш код на ошибки. Если всё верно, он превращает его не в машинный код, а в IL-код (Intermediate Language). Это универсальный язык, который понимают все версии .NET.

    Этап 2: JIT-компиляция (Just-In-Time)

    Когда пользователь запускает вашу программу, в дело вступает CLR. Внутри неё работает JIT-компилятор. Он берет IL-код и «на лету» переводит его в машинный код, оптимизированный именно под тот процессор, на котором сейчас запущена программа.

    > Интересный факт: Благодаря такой двухступенчатой системе, программу на C# можно (теоретически) запустить на любом компьютере, где установлен .NET, без переписывания кода. Это называется кроссплатформенностью.

    !Процесс превращения исходного кода C# в машинные инструкции

    Структура простейшей программы

    Теперь, когда мы понимаем теорию, давайте посмотрим на практику. Любая программа на C#, даже самая сложная игра или банковская система, состоит из определенных строительных блоков.

    Рассмотрим классический пример «Hello, World!»:

    Давайте разберем каждую строчку, как анатомы.

    1. Директива using

    using System;

    Эта строка говорит компилятору: «Мы хотим использовать готовые инструменты из набора System». Пространство имен System — это базовая библиотека .NET, в которой хранятся фундаментальные вещи, например, работа с текстом, математикой и консолью. Если убрать эту строку, нам пришлось бы писать полное имя команды: System.Console.WriteLine.

    2. Пространство имен (namespace)

    namespace MyFirstApp { ... }

    Пространства имен нужны для организации кода. Представьте, что пространство имен — это фамилия. В мире может быть много людей с именем «Иван», но «Иван Петров» — конкретный человек. Так и в программировании: у вас может быть класс Program, и в другой библиотеке может быть класс Program. Чтобы они не конфликтовали, мы оборачиваем наш код в уникальное пространство имен MyFirstApp.

    3. Класс (class)

    class Program { ... }

    C# — это объектно-ориентированный язык. Здесь всё должно находиться внутри классов. Класс — это контейнер, который описывает данные и поведение. Пока что воспринимайте класс просто как обязательную обертку для вашего кода.

    4. Метод Main

    static void Main(string[] args) { ... }

    Это самая важная часть. Метод Main — это точка входа в программу. Когда вы запускаете приложение, Windows (или другая ОС) ищет именно метод с названием Main и начинает выполнение команд оттуда. Если вы назовете его main (с маленькой буквы) или Start, программа просто не запустится (если не настроить это специально).

    5. Инструкция (Statement)

    Console.WriteLine("Hello, World!");

    Это сама команда. Мы обращаемся к классу Console (который находится в System) и вызываем его метод WriteLine (напиши строку). В скобках мы передаем текст, который хотим увидеть на экране.

    Основные правила синтаксиса

    C# — язык строгий. Он требует дисциплины и внимательности. Вот несколько золотых правил, которые нужно запомнить с первого дня:

    1. Регистрозависимость (Case Sensitivity)

    C# различает большие и маленькие буквы. Для него Console, console и CONSOLE — это три совершенно разных слова. * Правильно: Console.WriteLine * Ошибка: console.writeline

    2. Точка с запятой

    Каждая команда (инструкция) должна заканчиваться точкой с запятой ;. Это как точка в конце предложения в русском языке. Если вы забудете ;, компилятор выдаст ошибку и откажется собирать программу.

    3. Фигурные скобки

    Блоки кода (пространства имен, классы, методы) всегда заключаются в фигурные скобки { и }. Они показывают, где начинается и где заканчивается логическая часть программы. Важно следить за тем, чтобы каждая открытая скобка имела пару — закрывающую скобку.

    4. Комментарии

    Хороший код должен быть понятным, но иногда нужно оставить заметки для себя или коллег. Комментарии игнорируются компьютером и нужны только людям.

    * Однострочный комментарий начинается с //: Многострочный комментарий начинается с / и заканчивается */:

    Заключение

    Сегодня мы заложили первый камень в фундамент ваших знаний. Вы узнали, что C# — это мощный инструмент, который работает в паре с платформой .NET. Мы разобрали, как код превращается в программу, и изучили анатомию простейшего приложения.

    В следующих статьях мы начнем наполнять этот каркас смыслом: научимся хранить данные в переменных, считать и принимать решения в коде. Убедитесь, что вы хорошо поняли структуру Main и роль фигурных скобок, так как они будут сопровождать вас в каждой программе на C#.

    2. Типы данных, переменные и арифметические операции

    Типы данных, переменные и арифметические операции

    В предыдущей статье мы написали нашу первую программу «Hello, World!» и разобрали структуру приложения на C#. Но пока наша программа умеет только выводить текст. Она не умеет запоминать информацию, считать или взаимодействовать с пользователем. Чтобы это исправить, нам нужно познакомиться с фундаментальными понятиями программирования: переменными и типами данных.

    Что такое переменная?

    Представьте, что вы переезжаете в новую квартиру. У вас есть много вещей: книги, посуда, одежда. Чтобы перевезти их, вы используете коробки. На каждой коробке вы пишете маркером, что внутри: «Книги», «Кухня», «Одежда».

    В программировании переменная — это такая же коробка, но в оперативной памяти компьютера. Она имеет:

  • Имя (надпись на коробке), чтобы мы могли её найти.
  • Значение (содержимое коробки), то есть данные, которые в ней лежат.
  • Тип данных (размер и форма коробки), который определяет, что именно можно туда положить.
  • !Визуализация переменных как контейнеров разного типа для хранения данных

    Объявление и инициализация

    Чтобы создать переменную в C#, нужно сначала указать её тип, а затем имя. Это называется объявлением.

    Здесь int — это тип данных (целое число), а age — имя переменной. Теперь компьютер выделил место в памяти, но коробка пока пуста (или содержит мусор).

    Чтобы положить в неё значение, мы используем знак равно =. Это называется присваиванием.

    Чаще всего эти два действия объединяют в одну строку. Это называется инициализацией:

    > Важно: В C# знак = означает не математическое равенство, а команду «возьми значение справа и положи его в переменную слева».

    Основные типы данных

    C# — это язык со строгой типизацией. Это значит, что вы не можете положить ботинки в коробку для посуды. Если вы объявили переменную как число, вы не сможете записать в неё текст. Компилятор просто не позволит запустить такую программу.

    Рассмотрим самые важные типы данных, которые вы будете использовать в 90% случаев.

    Целые числа (int)

    Тип int (от англ. integer) используется для хранения целых чисел: 1, 10, -50, 1000000.

    Дробные числа (double)

    Если вам нужно хранить числа с запятой (например, вес, цену или точные координаты), используйте тип double.

    Обратите внимание: в коде в качестве разделителя используется точка, а не запятая.

    Текст (string)

    Тип string хранит последовательность символов. Текстовые значения всегда должны быть обернуты в двойные кавычки.

    Символ (char)

    Если вам нужно сохранить только одну букву или знак, используется тип char. Значение оборачивается в одинарные кавычки.

    csharp int age = 25; string name = "Ivan";

    // Старый способ Console.WriteLine("Меня зовут " + name + " и мне " + age + " лет.");

    // Интерполяция (новый и удобный способ) Console.WriteLine("Привет, {name}!"); csharp Console.Write("Введите ваш возраст: "); string input = Console.ReadLine(); // Допустим, ввели "20"

    int age = Convert.ToInt32(input); // Превращаем "20" в число 20 int futureAge = age + 5;

    Console.WriteLine($"Через 5 лет вам будет {futureAge}."); ``

    Заключение

    Сегодня мы разобрали «кирпичики», из которых строятся данные в программе. Вы узнали, что такое переменные, какие бывают типы данных (int, double, string, bool) и как выполнять над ними арифметические операции. Также мы научились «склеивать» строки и считывать ввод пользователя.

    В следующей статье мы научим нашу программу думать: мы разберем условные конструкции if и else`, чтобы код мог принимать решения в зависимости от данных.

    3. Логические операторы, ветвления и циклы

    Логические операторы, ветвления и циклы

    В предыдущих статьях мы научились создавать переменные и выполнять над ними арифметические операции. Наша программа уже умеет считать, но она всё ещё работает линейно: выполняет команды одну за другой, сверху вниз, без остановки. Однако реальная жизнь полна условий и выбора. Мы берем зонт, если идет дождь. Мы идем в магазин, пока не купим все продукты из списка.

    Чтобы наши программы стали по-настоящему умными, мы должны научить их двум вещам:

  • Принимать решения (ветвления).
  • Повторять действия (циклы).
  • Сегодня мы разберем инструменты, которые превращают простой калькулятор в сложный алгоритм.

    Логические значения и операторы сравнения

    Прежде чем принимать решения, нужно научиться задавать вопросы, на которые можно ответить «Да» или «Нет». В C# за это отвечает тип данных bool, который мы упоминали ранее. Он может хранить только true (истина) или false (ложь).

    Операторы сравнения

    Мы используем эти операторы, чтобы сравнивать значения. Результатом любой такой операции всегда будет bool.

    * == (Равно): Проверяет, равны ли два значения. Важно: не путайте с одиночным = (присваивание). * != (Не равно): Проверяет, отличаются ли значения. * > (Больше) и < (Меньше). * >= (Больше или равно) и <= (Меньше или равно).

    Логические операторы

    Часто нам нужно проверить сразу несколько условий. Например: «Я куплю телефон, если он дешевый И мощный». Для этого используются логические операторы. В математической логике это описывается специальными формулами.

    Рассмотрим операцию логического умножения (И):

    Где — результат, — первое условие, — второе условие, а символ обозначает логическое «И» (конъюнкцию). Результат будет истинным только тогда, когда истинны и , и .

    В C# используются следующие символы:

  • Логическое И (&&): Возвращает true, только если оба условия верны.
  • Логическое ИЛИ (||): Возвращает true, если хотя бы одно из условий верно.
  • Логическое НЕ (!): Инвертирует значение (превращает true в false и наоборот).
  • !Таблица истинности, показывающая результаты логических операций

    Ветвления: Конструкция if-else

    Самый популярный способ управления ходом программы — это конструкция if (если).

    Синтаксис выглядит так:

    Блок else не обязателен, но он полезен, если нужно предусмотреть альтернативный вариант действий.

    Каскад условий (else if)

    Если вариантов больше двух, мы можем использовать else if:

    Компьютер проверяет условия сверху вниз. Как только он находит первое истинное условие, он выполняет его блок и пропускает все остальные.

    !Блок-схема ветвления if-else

    Конструкция switch

    Иногда нам нужно проверить одну переменную на равенство множеству конкретных значений. Писать десять else if утомительно и некрасиво. Для этого существует оператор switch.

    Обратите внимание на ключевое слово break. Оно обязательно в конце каждого case, чтобы программа вышла из switch и не начала выполнять следующий блок кода по инерции.

    Циклы: Автоматизация повторений

    Представьте, что вам нужно вывести фразу «Привет!» 100 раз. Копировать строку кода 100 раз — плохая идея. Для этого существуют циклы.

    Цикл while (Пока)

    Это самый простой цикл. Он работает до тех пор, пока условие истинно.

    Разберем, что происходит в скобках:

  • int i = 0 — создается переменная-счетчик (срабатывает один раз в начале).
  • i < 5 — проверка условия перед каждым шагом. Если true, идем внутрь.
  • i++ — действие после каждого шага (увеличение счетчика).
  • Математически количество итераций в таком цикле можно выразить так:

    Где — количество повторений, — верхняя граница (в примере 5), а — начальное значение (в примере 0). Это верно для строгого неравенства < и шага 1.

    Управление циклами: break и continue

    Иногда нам нужно вмешаться в работу цикла:

    * break — немедленно прерывает цикл полностью. * continue — пропускает текущую итерацию и переходит к следующей.

    Заключение

    Сегодня мы сделали огромный шаг вперед. Теперь вы можете писать программы, которые не просто следуют инструкции, а анализируют данные и принимают решения. Логические операторы, ветвления if-else и циклы for и while — это «скелет» любого сложного алгоритма.

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

    4. Работа с массивами и создание пользовательских методов

    Работа с массивами и создание пользовательских методов

    В предыдущих статьях мы научились хранить данные в переменных и управлять потоком выполнения программы с помощью циклов и условий. Но представьте ситуацию: вам нужно написать программу для школы, которая хранит оценки 30 учеников в классе. Создавать 30 отдельных переменных (grade1, grade2, ..., grade30) — это долго, неудобно и делает код нечитаемым. А если учеников станет 100?

    Сегодня мы решим эту проблему с помощью массивов. Кроме того, мы научимся не дублировать код, создавая собственные методы (функции). Это поднимет ваши навыки программирования на качественно новый уровень.

    Массивы: Организованное хранение данных

    Массив (Array) — это структура данных, которая хранит набор значений одного типа под одним именем. Представьте себе длинный ряд почтовых ящиков в подъезде. Весь этот ряд — это массив. У каждого ящика есть свой уникальный номер (индекс), и в каждом ящике лежит письмо (значение).

    !Схематичное изображение структуры массива в памяти компьютера

    Объявление и создание массива

    Чтобы создать массив в C#, нужно указать тип данных, добавить квадратные скобки [] и дать массиву имя. После этого нужно выделить под него память с помощью ключевого слова new.

    Также можно сразу заполнить массив значениями при создании:

    Индексация: Самое важное правило

    В C#, как и в большинстве языков программирования, нумерация элементов массива начинается с нуля.

    * Первый элемент имеет индекс 0. * Второй элемент — индекс 1. * Последний элемент массива длиной имеет индекс .

    Почему так? Это связано с тем, как компьютер работает с памятью. Индекс — это по сути смещение от начала массива. Адрес ячейки памяти вычисляется по формуле:

    Где — итоговый адрес ячейки в памяти, — адрес начала массива, — номер элемента (начиная с 0), а — размер одного элемента в байтах (например, 4 байта для int). Если бы индекс начинался с 1, компьютеру пришлось бы каждый раз выполнять лишнюю операцию вычитания.

    Доступ к элементам

    Чтобы прочитать или записать значение, мы используем имя массива и индекс в квадратных скобках.

    Если вы попытаетесь обратиться к элементу, которого нет (например, numbers[10]), программа выдаст ошибку IndexOutOfRangeException и аварийно завершится.

    Перебор массивов

    Массивы и циклы созданы друг для друга. Чаще всего нам нужно выполнить одно и то же действие с каждым элементом массива (например, вывести на экран или найти сумму).

    Использование цикла for

    Цикл for идеально подходит, так как у нас есть счетчик i, который может служить индексом. У каждого массива есть свойство .Length, которое возвращает его длину.

    Разберем по частям:

  • Модификаторы (static): Пока просто запомните, что в консольных приложениях внутри Program мы используем static. Подробнее об этом мы поговорим в теме ООП.
  • Тип возвращаемого значения (void): Указывает, какой результат вернет метод. void (пустота) означает, что метод просто делает действие и ничего не возвращает.
  • Имя метода (SayHello): Принято называть методы глаголами, используя PascalCase (каждое слово с большой буквы).
  • Параметры (string name): Данные, которые метод получает для работы.
  • Вызов метода

    Чтобы метод сработал, его нужно вызвать внутри Main (или другого метода).

    Возвращаемые значения

    Часто нам нужно, чтобы метод что-то посчитал и вернул результат, который мы сможем сохранить в переменную. Для этого вместо void мы пишем тип данных (например, int), а внутри метода используем ключевое слово return.

    Ключевое слово return немедленно завершает работу метода. Любой код, написанный после return, никогда не выполнится.

    Область видимости переменных

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

    Это позволяет использовать одинаковые имена переменных (например, i для счетчиков) в разных методах без конфликтов.

    Заключение

    Сегодня мы освоили два мощнейших инструмента. Массивы позволяют нам работать с большими объемами данных, а методы помогают структурировать код, делая его чистым и понятным. Теперь вы можете создавать сложные программы, разбивая большие задачи на маленькие подзадачи-методы.

    В следующей статье мы перейдем к одной из самых важных тем в C# — объектно-ориентированному программированию (ООП), где узнаем, как создавать свои собственные типы данных.

    5. Основы ООП: классы, объекты и инкапсуляция

    Основы ООП: классы, объекты и инкапсуляция

    В предыдущих статьях мы прошли долгий путь: от простых переменных до массивов и методов. Мы научились писать программы, которые могут считать, принимать решения и повторять действия. Однако, когда программы становятся большими, управлять сотнями переменных и десятками методов становится сложно. Код превращается в «спагетти» — запутанный клубок, в котором трудно разобраться.

    Сегодня мы переходим к новой парадигме, которая изменила мир разработки программного обеспечения. Мы начинаем изучать Объектно-Ориентированное Программирование (ООП). Это подход, который позволяет моделировать в коде реальные вещи и процессы.

    Что такое ООП?

    До этого момента мы писали код в процедурном стиле: у нас были данные (переменные) и действия над ними (методы), но они жили отдельно друг от друга. ООП предлагает объединить данные и поведение в единую сущность — объект.

    Посмотрите вокруг. Мир состоит из объектов: стол, компьютер, кот, автомобиль. У каждого объекта есть:

  • Состояние (характеристики): цвет, вес, скорость, имя.
  • Поведение (действия): ехать, мяукать, включаться.
  • В C# мы создаем программы, описывая такие объекты и заставляя их взаимодействовать друг с другом.

    Класс и Объект: в чем разница?

    Это самый важный концептуальный барьер для новичков. Давайте разберем его раз и навсегда.

    Класс — это чертеж, шаблон или схема. Он описывает, каким может быть* объект, но сам по себе не содержит данных. * Объект (или экземпляр класса) — это конкретная реализация этого чертежа, созданная в памяти компьютера.

    !Иллюстрация различия между классом (чертеж) и объектами (реальные дома), созданными по этому чертежу

    Пример из жизни: У архитектора есть чертеж дома (Класс). По этому одному чертежу строители могут построить целый поселок из 50 домов (Объекты). Дома могут отличаться цветом стен или жильцами, но структура у них одна, заданная чертежом.

    Создание первого класса

    В C# классы создаются с помощью ключевого слова class. Давайте создадим класс для описания робота.

    Мы только что создали новый тип данных Robot. Но пока это просто описание.

    Создание объекта

    Чтобы «оживить» робота, нам нужно создать экземпляр класса в методе Main. Для этого используется ключевое слово new.

    Обратите внимание: переменные name и batteryLevel у каждого робота свои. Изменение заряда у bot1 никак не повлияет на bot2.

    Инкапсуляция: защита данных

    В примере выше мы использовали слово public перед переменными. Это означает, что кто угодно может изменить их из любой части программы. Представьте, что кто-то написал такой код:

    С точки зрения синтаксиса C# это верно (число -500 помещается в int). Но с точки зрения логики — это катастрофа. Заряд батареи не может быть отрицательным. Робот сломается.

    Здесь на сцену выходит первый принцип ООП — Инкапсуляция.

    > Инкапсуляция — это механизм, который объединяет данные и код, манипулирующий этими данными, а также защищает их от внешнего вмешательства и неправильного использования.

    Мы должны скрыть внутренние детали работы робота и предоставить безопасный интерфейс для управления им. Для этого используются модификаторы доступа:

    * public (публичный) — доступно всем. * private (приватный) — доступно только внутри самого класса. Если вы не укажете модификатор, в C# он будет private по умолчанию.

    !Метафора инкапсуляции: данные защищены внутри объекта, доступ к ним возможен только через специальные методы

    Геттеры и сеттеры

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

    Теперь мы не можем случайно сломать робота, присвоив ему -500%. Метод SetBattery выступает в роли стража.

    Свойства (Properties)

    Писать методы Get... и Set... для каждой переменной — это долго и делает код громоздким. Разработчики C# придумали элегантное решение — Свойства.

    Свойство выглядит как поле, но работает как пара методов. Внутри него есть блоки get (получить) и set (установить).

    Использование:

    Автоматические свойства

    Если вам не нужна сложная логика проверки (как с зарядом батареи), а нужно просто хранить данные, можно использовать сокращенную запись:

    Компилятор сам создаст скрытое приватное поле и методы для него. Это стандарт де-факто в современном C#.

    Конструкторы: Рождение объекта

    Когда мы пишем new Robot(), мы вызываем особый метод, который называется конструктор. Его задача — подготовить объект к работе (инициализировать его).

    По умолчанию создается пустой робот. Но что, если мы хотим, чтобы робот рождался сразу с именем?

    Теперь мы обязаны дать имя при создании:

    Заключение

    Сегодня мы заложили фундамент объектно-ориентированного программирования. Вы узнали, что:

  • Класс — это шаблон, а Объект — конкретный экземпляр.
  • Данные и методы живут вместе внутри объекта.
  • Инкапсуляция защищает данные от некорректного использования с помощью модификаторов private и public.
  • Свойства в C# — это удобный способ управлять доступом к данным.
  • В следующей статье мы разберем еще два столпа ООП: Наследование (как создавать новые классы на основе старых) и Полиморфизм (как работать с разными объектами одинаково).