Fundamentals

Вступ до екосистеми .NET

Комплексний огляд платформи .NET: історія, архітектура, інструменти та сучасні можливості

Навіщо нам .NET? Проблема з реального світу

Уявіть, що ви розробник у 2000-му році. Ви хочете створити застосунок, який працюватиме на Windows, виконуватиме складні бізнес-операції, взаємодіятиме з базами даних і забезпечуватиме безпеку даних користувачів. У вас є кілька варіантів:

  • C/C++: Надзвичайно швидкий, але складний. Управління пам'яттю вручну — це джерело помилок.
  • Visual Basic: Простий, але обмежений у можливостях.
  • Java: Кросплатформенний, але не інтегрований з Windows ecosystemою.
Проблема: Розробникам потрібна була платформа, яка поєднує продуктивність C++, простоту Visual Basic та безпеку керованого середовища, з глибокою інтеграцією у Windows.

Microsoft створила .NET Framework як відповідь на цей виклик. Сьогодні .NET — це потужна, кросплатформенна екосистема для створення будь-яких типів застосунків.


Еволюція .NET: Від Windows-Only до Cross-Platform Giant

Історична хронологія

Loading diagram...
timeline
title Еволюція .NET платформи
2002 : .NET Framework 1.0
: Windows-only
: Web Forms
2010 : .NET Framework 4.0
: WPF, WCF, LINQ
: Mono (community)
2016 : .NET Core 1.0
: Cross-platform
: Open Source
2020 : .NET 5
: Unified platform
: Single .NET
2025 : .NET 10
: Performance boost
: Native AOT

Три покоління .NET

Характеристика.NET Framework.NET CoreModern .NET (5+)
ПлатформиWindows onlyWindows, Linux, macOSWindows, Linux, macOS, mobile, IoT
Open Source❌ Ні✅ Так✅ Так
ПродуктивністьБазоваВисокаНадзвичайно висока
DeploymentSystem-wideSide-by-sideSide-by-side + Native AOT
ПідтримкаДо 2029 (.NET Framework 4.8)ЗавершеноАктивна (LTS: .NET 10)
Use CasesLegacy apps, WinForms, WPFModern web, microservicesУсе: web, mobile, desktop, cloud, ML
Важливо: .NET Framework (4.8) все ще підтримується Microsoft, але нові проєкти повинні використовувати modern .NET (.NET 10 і надалі). .NET Core (1.x-3.x) більше не підтримується.

Що таке .NET? Фундаментальні концепції

Академічне визначення

.NET Platform

.NET (дотнет) — це безкоштовна, кросплатформенна, відкрита (open-source) платформа розробки від Microsoft для створення різноманітних типів застосунків: веб-додатків, мобільних аплікацій, desktop-програм, хмарних сервісів, ігор, IoT-рішень та систем машинного навчання.

Ключові компоненти екосистеми

Runtime (CLR)

Середовище виконання коду з автоматичним управлінням пам'яттю (Garbage Collection), JIT-компіляцією та системою безпеки.

Base Class Library (BCL)

Велика стандартна бібліотека класів для роботи з файлами, мережею, колекціями, багатопотоковістю та іншим.

Languages

Підтримка множини мов: C#, F#, Visual Basic. Усі компілюються в проміжний код (IL).

Tools & SDK

Інструменти розробки: .NET CLI, NuGet (менеджер пакетів), IDE (Visual Studio, Rider, VS Code).

Аналогія з реального світу

Уявіть .NET як універсальну кухню з професійним обладнанням:

  • CLR (Runtime) — це кухонна плита та духовка: ви готуєте свою страву (код), а вони забезпечують необхідне тепло (виконання) та контролюють процес.
  • BCL (Base Class Library) — це набір інструментів та інгредієнтів: ножі, каструлі, сіль, спеції — усе, що потрібно для базового приготування.
  • C#, F# (Languages) — це рецепти різних кухонь: італійська паста (C#), французька випічка (F#) — різні підходи, але всі використовують одну кухню.
  • .NET SDK — це кухар-інструктор: допомагає правильно організувати процес та дає поради.

CLR: Серце платформи

Архітектура Common Language Runtime

Loading diagram...
graph TD

    %% Компоненти компіляції
    A["C# Source Code"] --> B["[C# Compiler (Roslyn)](https://github.com/dotnet/roslyn)"]
    B --> C["IL (Intermediate Language)"]
    C --> D["CLR (Common Language Runtime)"]

    %% Компоненти CLR
    D --> E["JIT Compiler"]
    D --> F["Garbage Collector"]
    D --> G["Type Safety Verification"]
    D --> H["Exception Handler"]
    D --> I["Security Manager"]

    E --> J["Native Machine Code"]
    J --> K["CPU Execution"]

    style A fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
    style B fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
    style C fill:#64748b,stroke:#334155,color:#ffffff
    style D fill:#f59e0b,stroke:#b45309,color:#ffffff
    style E fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
    style F fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
    style G fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
    style H fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
    style I fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
    style J fill:#64748b,stroke:#334155,color:#ffffff
    style K fill:#64748b,stroke:#334155,color:#ffffff

Що робить CLR?

Завантаження та верифікація

CLR завантажує ваш скомпільований код (IL) та перевіряє його безпеку типів (type safety). Це означає, що неможливо випадково звернутися до пам'яті, на яку ви не маєте права.

JIT-компіляція

Just-In-Time Compiler перетворює IL-код у нативний машинний код безпосередньо під час виконання. Це відбувається один раз для кожного методу при першому виклику.

Управління пам'яттю

Garbage Collector (GC) автоматично відстежує об'єкти в пам'яті та звільняє ті, які більше не використовуються. Ви не пишете free() або delete як у C++.

Обробка помилок

CLR централізовано обробляє виняткові ситуації (exceptions) та забезпечує структурований механізм відновлення.

Безпека виконання

Code Access Security (CAS) та інші механізми контролюють, які операції дозволені вашому коду (доступ до файлів, мережі тощо).

Переваги керованого коду (Managed Code):
  • Автоматичне управління пам'яттю → менше витоків пам'яті (memory leaks)
  • Type safety → менше помилок доступу до пам'яті
  • Кросплатформенність → один код працює на різних ОС
  • Безпека → ізоляція та контроль доступу

IL та JIT: Магія компіляції

Compilation Pipeline: Від C# до Machine Code

using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine("Hello, .NET!");
    }
}

Процес компіляції: Два етапи

Loading diagram...
sequenceDiagram
participant Dev as Розробник
participant Compiler as CSharp Compiler
participant IL as IL Assembly
participant CLR as CLR Runtime
participant JIT as JIT Compiler
participant CPU as Processor

Dev->>Compiler: Пише CSharp код
Compiler->>IL: Компілює в IL (.dll/.exe)
Note over IL: Portable, platform-agnostic

Dev->>CLR: Запускає програму
CLR->>IL: Завантажує assembly
CLR->>JIT: Виклик методу вперше
JIT->>CPU: Компілює IL → Native Code
Note over CPU: Код виконується

CLR->>CPU: Повторний виклик методу
Note over CPU: Використовує закешований native code (без JIT)

Tiered Compilation: Розумна оптимізація

Modern .NET використовує багаторівневу компіляцію (Tiered Compilation):

TierОписПеревагиКоли використовується
Tier 0Швидка, мінімально оптимізована компіляціяШвидкий старт застосункуПерший виклик методу
Tier 1Повна оптимізація з профілюваннямМаксимальна продуктивністьПісля збору статистики (hot paths)
Profile-Guided Optimization (PGO): CLR збирає дані про виконання коду (які гілки if часто виконуються, які типи передаються) та використовує їх для повторної оптимізації коду в Tier 1.

RyuJIT: Оптимізація під капотом

RyuJIT — це назва сучасного JIT-компілятора в .NET. Він виконує численні оптимізації:

1. Method Inlining (Вбудовування методів)

Замість виклику маленького методу, JIT вставляє його код безпосередньо у місце виклику, усуваючи overhead виклику функції.

public int Add(int a, int b) => a + b;

public void Calculate()
{
    int result = Add(5, 10); // Method call overhead}

2. Loop Unrolling (Розгортання циклів)

JIT може розгорнути малі цикли для зменшення кількості перевірок умов і збільшення інструкцій, які CPU може виконати паралельно.

int sum = 0;
for (int i = 0; i < 4; i++)
{
    sum += array[i];
}

3. SIMD Vectorization (Векторизація)

RyuJIT автоматично використовує SIMD (Single Instruction, Multiple Data) інструкції процесора для обробки декількох значень одночасно.

// System.Numerics.Vectors example
using System.Numerics;

Span<float> values = stackalloc float[8] { 1, 2, 3, 4, 5, 6, 7, 8 };
Span<float> results = stackalloc float[8];

var vector1 = new Vector<float>(values);
var vector2 = new Vector<float>(2.0f); // All elements = 2.0

var resultVector = vector1 * vector2; // Multiplies 8 floats in ONE CPU instructionresultVector.CopyTo(results);

// Results: [2, 4, 6, 8, 10, 12, 14, 16]
Performance Impact: SIMD може прискорити обчислення в 4-8 разів для операцій над масивами чисел (графіка, ML, обробка зображень).

CTS та CLS: Універсальна мова типів

Common Type System (CTS)

CTS — це специфікація, яка визначає, як типи даних описуються та використовуються в .NET. Вона забезпечує сумісність між мовами.

Loading diagram...
graph LR

    A["CTS Type System"] --> B["Value Types"]
    A --> C["Reference Types"]
    B --> D["Structures"]
    B --> E["Enumerations"]
    B --> F["Built-in types"]
    C --> G["Classes"]
    C --> H["Interfaces"]
    C --> I["Delegates"]
    C --> J["Arrays"]

    style A fill:#f59e0b,stroke:#b45309,color:#ffffff
    style B fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
    style C fill:#3b82f6,stroke:#1d4ed8,color:#ffffff
    style D fill:#64748b,stroke:#334155,color:#ffffff
    style E fill:#64748b,stroke:#334155,color:#ffffff
    style F fill:#64748b,stroke:#334155,color:#ffffff
    style G fill:#64748b,stroke:#334155,color:#ffffff
    style H fill:#64748b,stroke:#334155,color:#ffffff
    style I fill:#64748b,stroke:#334155,color:#ffffff
    style J fill:#64748b,stroke:#334155,color:#ffffff

Приклад міжмовної сумісності

// MyLibrary.dll
namespace MathLib
{
    public class Calculator
    {
        public int Add(int a, int b) => a + b;
    }
}

Common Language Specification (CLS)

CLS — це підмножина CTS, яка визначає мінімальний набір функцій, які повинен підтримувати будь-який .NET-сумісний компілятор.

CLS-Compliance: Якщо ви створюєте бібліотеку, яку планують використовувати інші розробники (можливо, з F# або VB), переконайтеся, що публічний API використовує лише CLS-compliant типи.

Наприклад:

  • public UInt32 GetId()UInt32 не CLS-compliant
  • public int GetId()int (Int32) CLS-compliant

Налаштування середовища розробки

Вибір IDE: Порівняння інструментів

IDEПлатформаЛіцензіяПеревагиНедолікиРекомендовано для
Visual StudioWindows, macOSCommunity: Free
Pro/Enterprise: Paid
Найпотужніший debugger, інтеграція з Azure, GUI-дизайнериВажкий, повільний на старих ПКEnterprise-розробка, WPF, WinForms
JetBrains RiderWin, Mac, LinuxПлатна (підписка)Швидкий, інтелектуальний ReSharper, кросплатформеннийПотребує підпискуПрофесійна розробка, великі проєкти
VS Code + C# Dev KitWin, Mac, LinuxБезкоштовнаЛегкий, швидкий, розширюваний, великий MarketplaceМенше функцій для складного debuggingWeb-розробка, скрипти, легкі проєкти

Встановлення .NET SDK

Завантаження .NET SDK

Відвідайте офіційний сайт: https://dotnet.microsoft.com/download

Завантажте останню LTS (Long-Term Support) версію. NET 10.

Установка

winget install Microsoft.DotNet.SDK.10

Перевірка встановлення

Відкрийте термінал та виконайте:

dotnet --version

Очікуваний вивід:

10.0.100
Якщо ви бачите номер версії, .NET SDK встановлено успішно!

.NET CLI: Mastering Command Line Interface

Основні команди: Швидкий довідник

КомандаОписПриклад
dotnet newСтворює новий проєкт з шаблонуdotnet new console -n MyApp
dotnet buildКомпілює проєктdotnet build
dotnet runКомпілює та запускає проєктdotnet run
dotnet watchАвтоматично перекомпілює при змінахdotnet watch run
dotnet publishПублікує застосунок для deploymentdotnet publish -c Release
dotnet add packageДодає NuGet-пакетdotnet add package Newtonsoft.Json
dotnet restoreВідновлює залежностіdotnet restore
dotnet testЗапускає тестиdotnet test

Workflow: Створення першого застосунку

Створення проєкту

dotnet new console -n HelloDotNet
cd HelloDotNet

Ця команда створює консольний застосунок з назвою HelloDotNet.

Структура проєкту

Перегляд коду

// Top-level statements (C# 9+)
Console.WriteLine("Hello, World!");

Запуск застосунку

dotnet run

Вивід:

Hello, World!

Watch mode (автоматична перекомпіляція)

dotnet watch run

Тепер змініть Program.cs:

Console.WriteLine("Hello, .NET! 🚀");

Збережіть файл — застосунок автоматично перезапуститься!

Публікація для production

dotnet publish -c Release -r win-x64 --self-contained

Пояснення:

  • -c Release → Оптимізована збірка (Release mode)
  • -r win-x64 → Runtime Identifier (Windows 64-bit)
  • --self-contained → Включає .NET runtime у пакет (не потребує встановленого .NET на цільовій машині)
Підказка: Використовуйте dotnet watch під час розробки — це заощаджує величезну кількість часу, автоматично перекомпілюючи код при кожній зміні.

.NET 10: Сучасні можливості

Modern .NET еволюціонує з неймовірною швидкістю. Ось найважливіші інновації останніх версій:

.NET 10 (LTS - Листопад 2025)

Long-Term Support до 2028
ФункціяОписПереваги
Discriminated UnionsНативна підтримка union types (як у F#)Безпечніша робота з варіантами типів
Primary Constructors EnhancedРозширення на всі типи класівМенше boilerplate коду
Performance ImprovementsSIMD, PGO за замовчуванням, оптимізації GC та компілятораДо 40% швидше у веб-сценаріях порівняно з .NET 8
Native AOT MaturityПокращена підтримка Ahead-of-Time компіляціїStartup за <1ms, менший розмір (~10MB standalone apps)
JSON Source Generators v3Нове покоління source generators для System.Text.JsonНайшвидша серіалізація, zero-allocation
Blazor EnhancementsWebAssembly preloading, form validation improvementsКращий UX для веб-застосунків
Рекомендація: .NET 10 є поточною LTS версією. Використовуйте її для всіх нових production-проєктів.

Порівняння останніх версій

ВерсіяТип підтримкиПідтримка доКлючові особливості
.NET 8LTSЛистопад 2026Blazor SSR, TimeProvider, Native AOT improvements
.NET 9STSТравень 2026Hybrid Cache, LINQ improvements (CountBy, AggregateBy), OpenAI SDK
.NET 10LTSЛистопад 2028Discriminated Unions, Performance boost, Enhanced Primary Constructors

IL Analysis & Protection: Reflectors та Obfuscators

Що таке Reflectors (Дизасемблери)?

Reflector (Decompiler) — це інструмент, який перетворює скомпільований .NET код (IL) назад у читабельний C#/F# код. Оскільки IL містить багато метаданих (назви класів, методів, змінних), декомпіляція є дуже точною.

Популярні Reflectors

ІнструментТипМожливостіUse Cases
ILSpyOpen-sourceDecompiler, Assembly Browser, Find ReferencesВивчення чужих бібліотек, reverse engineering
dnSpyOpen-sourceDecompiler + Debugger + IL EditorНалагодження сторонніх DLL, патчінг
dotPeekFree (JetBrains)Decompiler, Navigation, Export to ProjectДослідження коду, інтеграція з Rider
ILDasmOfficial (Microsoft)IL Viewer (не C#)Перегляд raw IL коду

Приклад: Decompiling з ILSpy

Компілюємо простий застосунок

namespace MyApp;

public class Calculator
{
    private const string SecretKey = "MyPassword123"; 
    public int Multiply(int a, int b)
    {
        return a * b;
    }
}
dotnet build -c Release

Відкриваємо DLL у ILSpy

  1. Завантажте ILSpy: https://github.com/icsharpcode/ILSpy
  2. Відкрийте bin/Release/net10.0/MyApp.dll
  3. ILSpy показує оригінальний C# код, включаючи константу SecretKey!

Проблема безпеки: Будь-хто може побачити ваші константи, алгоритми, навіть ключі API, якщо ви їх хардкодите!

Obfuscators (Обфускатори): Захист коду

Obfuscator — це інструмент, який перетворює IL-код, роблячи його важким для читання та аналізу, але зберігаючи функціональність.

Методи обфускації

ТехнікаОписПриклад
Name ObfuscationЗаміна зрозумілих назв на випадковіCalculatorA, Multiplya1b2
Control Flow ObfuscationУскладнення логіки (додавання мертвого коду, заплутування if)if (true)if (a ^ b == c)
String EncryptionШифрування рядкових літералів"MyPassword" → зашифрована послідовність
Anti-TamperingВиявлення модифікацій кодуПеревірка checksum при старті
Anti-DebuggingВиявлення debuggerDebugger.IsAttached → Exit

Популярні Obfuscators

ІнструментТипРівень захистуВартість
DotfuscatorCommercial (Microsoft)Високий (Enterprise: anti-tamper, watermarking)Free (Community), Paid (Pro/Enterprise)
ConfuserExOpen-sourceСередній (name, control flow, constants)Безкоштовно
SmartAssemblyCommercial (Red Gate)Високий (feature merging, pruning)Платний
.NET ReactorCommercialВисокий (native code wrapping)Платний

Приклад обфускації

public class Calculator
{
    public int Multiply(int a, int b)
    {
        return a * b;
    }
}
Обмеження Obfuscation:
  • Не є абсолютним захистом (досвідчений reverse engineer може частково відновити логіку)
  • Може погіршити performance (особливо control flow obfuscation)
  • Ускладнює debugging production issues (stack traces стають нечитабельними)

Коли використовувати Reflectors та Obfuscators?

✅ Використовуйте Reflectors

  • Вивчення внутрішніх механізмів .NET/сторонніх бібліотек
  • Debugging проблем у залежностях
  • Reverse engineering legacy code без вихідників
  • Навчання (розуміння, як реалізовані LINQ, async/await)

🔒 Використовуйте Obfuscators

  • Комерційні desktop-застосунки (захист інтелектуальної власності)
  • Ліцензійні алгоритми (криптографія, ML-моделі)
  • Запобігання крадіжці API-ключів
  • Ускладнення створення піратських копій
Best Practice: Для веб-застосунків (ASP.NET Core API) обфускація менш критична, оскільки код виконується на вашому сервері. Для desktop/mobile — обфускація рекомендована.

Перевірка знань

Закріпіть отримані знання, пройшовши короткий тест:

Примітка: Якщо тест не відображається, перейдіть за прямим посиланням.

Резюме та Практичні завдання

Що ми дізналися

Історія .NET

Еволюція від .NET Framework (Windows-only) до Modern .NET (cross-platform, open-source).

CLR Architecture

Як CLR виконує код: IL → JIT → Native Code, Garbage Collection, Type Safety.

JIT Optimizations

Tiered Compilation, PGO, RyuJIT оптимізації (Inlining, Loop Unrolling, SIMD).

CTS/CLS

Універсальна система типів для міжмовної сумісності.

.NET CLI

Робота з dotnet: new, build, run, watch, publish.

Modern Features

Native AOT, Performance improvements, Discriminated Unions (.NET 10).

IL Tools

Reflectors (ILSpy) для аналізу, Obfuscators (ConfuserEx) для захисту.

Практичні завдання

Beginner: Перший .NET застосунок

  1. Створіть консольний проєкт:
    dotnet new console -n MyCalculator
    
  2. Реалізуйте клас Calculator з методами Add, Subtract, Multiply, Divide.
  3. Викличте методи з Main та виведіть результати.
  4. Опублікуйте застосунок у режимі Release:
    dotnet publish -c Release
    

Intermediate: IL Analysis

  1. Компілюйте ваш Calculator у Release mode.
  2. Завантажте ILSpy та відкрийте скомпільовану DLL.
  3. Знайдіть метод Add та подивіться IL код.
  4. Порівняйте IL-код для Debug vs Release збірок (Release оптимізованіший).

Advanced: Obfuscation Experiment

  1. Завантажте ConfuserEx: https://github.com/mkaring/ConfuserEx
  2. Обфускуйте вашу DLL:
    • Увімкніть Name Obfuscation
    • Увімкніть Control Flow Obfuscation
  3. Відкрийте обфусковану DLL у ILSpy.
  4. Зверніть увагу, наскільки важче читати код.
Примітка: Обфускація може зламати Reflection-based код (наприклад, серіалізацію JSON). Завжди тестуйте після обфускації!

Вітаємо! Ви завершили вступ до екосистеми .NET. Тепер ви розумієте, як працює платформа "під капотом", як налаштувати середовище та які інструменти використовувати для розробки та захисту коду.Наступний крок: Переходьте до 1.2. Program Structure та дізнайтеся про структуру C# програм, namespaces та top-level statements!