C# с абсолютного нуля до профессиональной разработки
Последовательный курс RAIMBALT Learn: сначала понимание, затем минимальный пример, самостоятельная практика, проверка и проект. Предыдущий опыт программирования не требуется.
Последовательный курс RAIMBALT Learn: сначала понимание, затем минимальный пример, самостоятельная практика, проверка и проект. Предыдущий опыт программирования не требуется.
Переходи дальше только после того, как можешь воспроизвести идею самостоятельно и понимаешь, зачем она нужна.
После модулей закрепляй материал практикой и проверками. Курс считается освоенным только после выполнения критериев, а не после простого открытия всех страниц.
Начинаем вообще без кода. Сначала разберём, что такое программа, программирование и зачем нужен C#.
Перед первой строкой кода разберём правила курса: как читать урок, как практиковаться и почему следующий урок бывает закрыт.
Теперь готовим инструменты и учимся отличать решение Visual Studio, проект и обычный файл исходного кода.
Только теперь пишем первую строку C# и разбираем каждый её элемент, а не копируем как заклинание.
После вывода текста учимся сохранять значение под понятным именем.
Разные данные требуют разных типов. Изучаем только те типы, которые уже можно понять на бытовых примерах.
Программа начинает взаимодействовать с человеком: задаёт вопрос и получает текстовый ответ.
Учимся безопасно превращать текст пользователя в число без падения программы.
Теперь объединяем переменные и числа в понятный расчёт, но без скрытых шагов.
Условие превращает программу из последовательности команд в систему, которая реагирует на данные.
Реальные правила редко состоят из одной проверки. Логические операторы объединяют несколько условий.
Когда программа сравнивает одно значение с несколькими вариантами, switch часто читается проще длинной цепочки if.
Цикл for нужен, когда заранее понятно, сколько повторений требуется или нужен индекс.
while подходит, когда количество повторений заранее неизвестно и зависит от состояния.
foreach позволяет пройти по каждому элементу массива или списка без ручного управления индексом.
Иногда цикл нужно закончить раньше или пропустить только текущую итерацию.
Метод — отдельный блок программы с понятным названием. Он помогает не копировать одинаковый код и делить большую задачу на маленькие.
Иногда метод должен не печатать ответ, а вычислить его и отдать вызывающему коду.
Переменная существует только там, где она объявлена. А несколько методов могут иметь одно имя, если отличаются параметры.
C# умеет передавать значения в метод разными способами. Эти возможности полезны, но их нужно применять осознанно.
До этого мы использовали готовые типы. Теперь создадим собственный тип, который описывает реальную сущность.
Публичные поля дают слишком свободный доступ к состоянию. Свойства позволяют сделать интерфейс объекта аккуратнее.
Конструктор выполняется при `new` и помогает не забыть обязательные данные.
Иногда несколько типов имеют общую основу. Наследование позволяет вынести общие данные и поведение, но использовать его нужно только при реальном отношении «является».
Интерфейс описывает, что объект умеет делать, не привязывая код к одному конкретному классу.
Массив хранит несколько значений одного типа и имеет фиксированный размер.
List похож на массив, но позволяет удобно добавлять и удалять элементы.
Dictionary хранит пары ключ → значение, когда нужен поиск не по позиции, а по уникальному ключу.
LINQ позволяет описывать выборку из коллекции: что оставить, как преобразовать и как отсортировать.
После фильтрации часто нужно получить другой вид данных, отсортировать или посчитать итог.
Исключение сообщает, что во время выполнения произошло нештатное событие.
Без хранения данных программа забывает состояние после закрытия. Начнём с обычного текстового файла.
JSON — текстовый формат данных. В C# объект можно сериализовать в JSON и восстановить обратно.
Некоторые операции тратят время не на вычисления, а на ожидание файла, сети или базы данных.
Если несколько операций не зависят друг от друга, их часто можно ожидать вместе.
Большая программа становится неудобной, если ввод, расчёты и хранение данных находятся в одном методе.
Тест запускает небольшой фрагмент логики и проверяет ожидаемый результат.
Файл подходит для простых данных, но многопользовательскому приложению нужны запросы, связи и надёжное хранение.
Пользовательский ввод нельзя безопасно вставлять в SQL через конкатенацию.
Собери фундамент курса в одну программу: модели, коллекции, LINQ, JSON, async и разделение ответственности.
Generics позволяют написать типобезопасный код без копирования почти одинаковых классов.
Generic-класс хранит или обрабатывает данные разных типов.
Иногда методу нужно передать не данные, а действие или правило.
Событие уменьшает прямую связанность между источником события и реакциями.
Класс, который читает ввод, считает, пишет файл и отправляет email, сложно менять и тестировать.
Зависимость лучше получать снаружи, чем создавать внутри класса через new.
GroupBy объединяет элементы по ключу и позволяет строить отчёты.
Теперь собери не просто консольный скрипт, а небольшой проект с разделением ответственности.
В этом уроке тема «Интерфейсы как контракт» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «Репозиторий: отделяем хранение данных» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «Собственные исключения» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «IDisposable и using» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «Dictionary и HashSet» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «SelectMany» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «Any, All и Contains» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «DateOnly, DateTimeOffset и TimeSpan» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «Параметризованные unit-тесты» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «Fake-зависимости в тестах» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «Big O на практике» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке тема «Итог C# Core» разбирается не как готовая команда, а как инструмент для конкретной задачи.
В этом уроке «SOLID на практике» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Dependency Inversion» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Dependency Injection» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Result pattern» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Domain model» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Immutable модели» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Records глубже» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Pattern matching глубже» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Generic constraints» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Span и Memory» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «IAsyncEnumerable» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Channel producer/consumer» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «SemaphoreSlim» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Deadlock mental model» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Retry и idempotency» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Cancellation design» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Allocation awareness» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Benchmark mindset» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Test doubles» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Integration tests» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Test data builders» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Nullable reference types» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Analyzers» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Structured logging» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Secrets и configuration» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Trust boundaries» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Background worker» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Clean boundaries» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Refactoring legacy code» разбирается от проблемы к решению, а не как набор команд.
В этом уроке «Профессиональный C# capstone» разбирается от проблемы к решению, а не как набор команд.