C# — язык программирования, а .NET — платформа, на которой выполняются программы на C#: среда выполнения CLR, стандартные библиотеки и инструменты сборки. .NET Framework — первая, только Windows-реализация этой платформы; ее последняя версия 4.8.1 поддерживается, но новых возможностей не получает. Новые проекты пишут на кроссплатформенном .NET (бывший .NET Core), актуальная LTS-версия — .NET 10 с C# 14.
Содержание
А фреймворки C# в бытовом смысле — прикладные надстройки поверх платформы: ASP.NET Core для веба, EF Core для баз данных, .NET MAUI, WPF и Avalonia для интерфейсов. Ниже — как устроено выполнение кода, чем .NET Framework отличается от .NET и что выбрать под задачу. Примеры проверены на .NET SDK 10.0.401 (runtime 10.0.12) в Linux-контейнере 24.09.2026.
Мини-словарь: что есть что
Эти слова постоянно путают, поэтому сначала разведем их.
| Термин | Что это | Пример |
|---|---|---|
| C# | Язык: синтаксис, типы, правила компиляции | int Square(int x) => x * x; |
| .NET (платформа) | CLR + библиотеки + SDK (компилятор, dotnet) |
.NET 10 |
| .NET Framework | Старая реализация .NET, только Windows | 4.8.1 |
| .NET Core, .NET 5+ | Новая кроссплатформенная реализация | .NET 8, .NET 10 |
| CLR | Среда выполнения: JIT-компиляция, сборка мусора, проверка типов | часть любого .NET |
| CIL (IL) | Промежуточный байт-код, в который компилируется C# | ldarg.0, mul, ret |
| BCL | Базовая библиотека классов | List<T>, File, HttpClient |
| Прикладной фреймворк | Каркас под класс задач, диктует структуру приложения | ASP.NET Core, WPF |
Важная граница: C# — не единственный язык .NET (есть F# и Visual Basic .NET), а .NET-программу можно запустить без Visual Studio — достаточно SDK и команды dotnet.
Как выполняется код на C
Путь программы от исходника до процессора выглядит так:
- Компилятор C# (Roslyn) превращает
.cs-файлы в сборку.dllили.exe. Внутри — не машинный код, а CIL и метаданные о типах. - При запуске CLR загружает сборку и проверяет метаданные.
- JIT-компилятор переводит метод в машинный код при первом вызове. Повторные вызовы используют уже готовый код.
- Сборщик мусора (GC) сам освобождает память объектов, на которые больше нет ссылок.
Это упрощенная модель. В современном .NET есть многоуровневая компиляция (сначала быстрый JIT, потом оптимизированный для «горячих» методов), предкомпиляция ReadyToRun и Native AOT, при котором приложение компилируется в машинный код заранее и JIT во время работы не нужен.
Управляемый и неуправляемый код
Управляемый код выполняется под контролем CLR: память освобождает GC, выход за границы массива дает исключение, а не порчу памяти. Весь обычный код на C# управляемый.
Неуправляемый код — нативные библиотеки на C/C++ и системные API. C# вызывает их через P/Invoke, но за память и корректность на той стороне CLR не отвечает. Режим unsafe в C# с указателями — промежуточный случай: код остается управляемым, но часть проверок снимается.
Пример: смотрим на CLR и CIL изнутри
Программа выводит, на какой среде она запущена, показывает байты CIL одного метода и выделяет память без ручного освобождения. Проект создается командой dotnet new console, запуск — dotnet run -c Release.
using System.Reflection;
using System.Runtime.InteropServices;
Console.WriteLine($"Среда выполнения: {RuntimeInformation.FrameworkDescription}");
Console.WriteLine($"ОС: {RuntimeInformation.OSDescription}");
Console.WriteLine($"Архитектура процесса: {RuntimeInformation.ProcessArchitecture}");
// Метод Square скомпилирован не в машинный код, а в CIL (промежуточный язык).
MethodInfo square = typeof(Calc).GetMethod(nameof(Calc.Square))!;
byte[] il = square.GetMethodBody()!.GetILAsByteArray()!;
Console.WriteLine($"CIL метода Square: {BitConverter.ToString(il)}");
Console.WriteLine($"Square(7) = {Calc.Square(7)}");
// Памятью управляет сборщик мусора (GC): освобождать объекты вручную не нужно.
long before = GC.GetTotalAllocatedBytes(precise: true);
var data = new byte[1_000_000];
long after = GC.GetTotalAllocatedBytes(precise: true);
Console.WriteLine($"Выделено под массив: ~{(after - before) / 1_000_000.0:F1} МБ, длина {data.Length}");
static class Calc
{
public static int Square(int x) => x * x;
}
Вывод в контейнере mcr.microsoft.com/dotnet/sdk:10.0 (строки про ОС и архитектуру на вашей машине будут другими):
Среда выполнения: .NET 10.0.12
ОС: Ubuntu 24.04.5 LTS
Архитектура процесса: Arm64
CIL метода Square: 02-02-5A-2A
Square(7) = 49
Выделено под массив: ~1.0 МБ, длина 1000000
Разбор по шагам:
FrameworkDescriptionназывает реализацию платформы. На .NET Framework там было бы.NET Framework 4.8..., на современном .NET —.NET 10.0.x.- Четыре байта
02-02-5A-2A— это CIL методаSquare:ldarg.0(положить аргумент на стек) дважды,mul(умножить),ret(вернуть). Машинный код для ARM64 или x64 из них строит JIT уже при запуске, поэтому одна и та же сборка работает на разных процессорах. - Массив на миллион байт создан без
mallocиfree: память выделил и позже освободит GC.
Одна оговорка: для такого однострочного метода отладочная и Release-сборка дали одинаковые байты. Если записать тот же метод с телом в фигурных скобках ({ return x * x; }), отладочная сборка (dotnet run без -c Release) выдает 00-02-02-5A-0A-2B-00-06-2A: добавляются nop, сохранение результата в локальную переменную и переход перед ret, которые упрощают пошаговую отладку. Release-сборка для этого варианта дает те же 02-02-5A-2A.
.NET Framework и .NET: в чем разница
Хронология коротко: .NET Framework 1.0 вышел в 2002 году, в 2016-м появился кроссплатформенный .NET Core 1.0. В 2020 году ветки объединили под именем .NET 5 (номер 4 пропустили, чтобы не путать с .NET Framework 4.x). С тех пор новая версия выходит каждый ноябрь: четные — LTS, нечетные — STS с более коротким сроком поддержки.
| Критерий | .NET Framework | .NET (Core, 5+) |
|---|---|---|
| ОС | Только Windows | Windows, Linux, macOS |
| Актуальная версия | 4.8.1, без новых возможностей | .NET 10 LTS, новая версия каждый ноябрь |
| Установка | Одна версия 4.x на систему, входит в Windows | Несколько версий рядом, можно встроить в приложение |
| Исходный код | Закрытый | Открытый (MIT) |
| Веб | ASP.NET MVC, Web Forms | ASP.NET Core |
| Десктоп | WinForms, WPF | WinForms и WPF (только Windows), MAUI, Avalonia |
Имя цели в .csproj |
net48, net481 |
net8.0, net10.0, net10.0-windows |
Как выбирать:
- Новый проект — .NET 10: LTS, кроссплатформенность, свежий C#.
- Поддержка старого приложения на .NET Framework — оставаться на 4.8.1, пока нет бюджета на миграцию. Web Forms и серверная часть WCF в современный .NET не перенесены, для них миграция — это переписывание.
- Библиотека для обоих миров — цель
netstandard2.0или несколько целей сразу (<TargetFrameworks>net48;net10.0</TargetFrameworks>).
Популярные фреймворки C# по задачам
Разница в терминах: платформа (.NET) исполняет код, библиотека (например, Newtonsoft.Json) вызывается из вашего кода, а фреймворк сам вызывает ваш код и задает структуру приложения.
| Задача | Фреймворк | Где работает | Когда брать иначе |
|---|---|---|---|
| Веб-API, сайты | ASP.NET Core (Minimal API, MVC, Razor Pages) | Windows, Linux, macOS, контейнеры | Старый сайт на ASP.NET MVC 5 живет на .NET Framework |
| Интерактивный веб-интерфейс на C# | Blazor (часть ASP.NET Core) | Сервер или браузер через WebAssembly | Для сложного SPA команда может выбрать JS-фреймворк |
| Работа с БД | Entity Framework Core | Везде, где .NET | Нужен полный контроль SQL — микро-ORM или ADO.NET |
| Десктоп под Windows | WPF, Windows Forms, WinUI 3 | Только Windows | Нужен Linux/macOS — Avalonia или MAUI |
| Кроссплатформенный UI | .NET MAUI, Avalonia (сторонний) | MAUI: Windows, macOS, Android, iOS; Avalonia: плюс Linux | Только Windows — проще WPF |
| Игры | Unity, Godot (C# как язык скриптов) | Зависит от движка | Unity исполняет C# на своем рантайме (Mono или IL2CPP), Godot 4 — на обычном .NET; экспорт C#-проекта Godot в веб пока не поддерживается |
| Тесты | xUnit, NUnit, MSTest | Везде, где .NET | Выбор по стилю команды |
| Распределенные системы | Orleans | Везде, где .NET | Обычный веб-сервис проще на ASP.NET Core |
Мобильная разработка на Xamarin закрыта: его поддержка завершилась в 2024 году, преемник — .NET MAUI.
Частая ошибка: WinForms на неправильной цели
Кроссплатформенность .NET не делает кроссплатформенными WinForms и WPF. Вот проект, который пытается собрать WinForms-приложение с обычной целью net10.0:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net10.0</TargetFramework>
<UseWindowsForms>true</UseWindowsForms>
</PropertyGroup>
</Project>
Фактический результат dotnet build (путь к SDK сокращен):
error NETSDK1136: The target platform must be set to Windows (usually by including '-windows' in the TargetFramework property) when using Windows Forms or WPF, or referencing projects or packages that do so.
Исправление — цель с суффиксом платформы: <TargetFramework>net10.0-windows</TargetFramework>. На Windows после этого проект собирается и запускается.
На Linux или macOS появится следующая ошибка:
error NETSDK1100: To build a project targeting Windows on this operating system, set the EnableWindowsTargeting property to true.
С <EnableWindowsTargeting>true</EnableWindowsTargeting> сборка проходит, но dotnet run в Linux-контейнере сообщает You must install or update .NET to run this application и Framework: 'Microsoft.WindowsDesktop.App'. Флаг разрешает только собрать проект вне Windows (например, на CI), запускать такое приложение по-прежнему нужно на Windows.
Как проверить, что установлено
Для современного .NET (Windows, Linux, macOS):
dotnet --list-sdks # SDK: собирают проекты
dotnet --list-runtimes # среды выполнения: запускают приложения
Вывод второй команды в том же контейнере:
Microsoft.AspNetCore.App 10.0.12 [/usr/share/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 10.0.12 [/usr/share/dotnet/shared/Microsoft.NETCore.App]
Здесь видно, что в .NET «фреймворк» — еще и технический термин: Microsoft.NETCore.App — базовый общий фреймворк, Microsoft.AspNetCore.App — веб, а Microsoft.WindowsDesktop.App (WinForms/WPF) ставится только на Windows.
Версию .NET Framework 4.x на Windows показывает PowerShell — команда только читает реестр:
Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full' | Select-Object Version, Release
Если не получилось
You must install or update .NET to run this application— на машине нет среды нужной версии. Сверьте версию из сообщения с выводомdotnet --list-runtimesи поставьте недостающий runtime.- Ошибка NETSDK1045 при сборке — SDK старше, чем цель в
.csproj. Обновите SDK или понизьтеTargetFramework. - Старая программа просит .NET Framework 3.5 — в Windows 10/11 он включается в «Компонентах Windows», а не ставится отдельным пакетом.
- Удалять .NET Framework 4.x в Windows 10/11 не нужно и нельзя — это часть системы. При сбоях сначала обновления Windows, потом официальная утилита .NET Framework Repair Tool.
Выводы
- C# — язык, .NET — платформа (CLR, библиотеки, SDK), .NET Framework — старая Windows-реализация этой платформы, остановленная на 4.8.1.
- Код на C# компилируется в CIL, а в машинный код его переводит JIT при запуске (или заранее при Native AOT); памятью управляет GC.
- Новые проекты — на .NET 10 LTS; .NET Framework остается для поддержки legacy-приложений.
- «Фреймворки C#» подбирают под задачу: ASP.NET Core для веба, EF Core для БД, WPF/WinForms для Windows-десктопа, MAUI или Avalonia для кроссплатформенного UI.
- WinForms и WPF работают только на Windows даже в современном .NET: цель
net10.0-windows.
Где применяется / связь с практикой
Освойте тему на практике
Разница между языком, платформой и фреймворком всплывает с первого проекта: какую цель указать в .csproj, почему приложение не запускается на сервере, можно ли перенести старый сервис на Linux. Если хочется пройти путь от синтаксиса C# до приложений на .NET системно, с практикой и разбором кода, посмотрите курс «C#-разработчик. Базовый уровень». Отдельные темы по .NET и смежным технологиям разбирают на открытых уроках Otus.
FAQ
Можно ли писать на C# без .NET?
Практически нет: C#-компилятор выдает CIL, которому нужна среда выполнения. Это может быть .NET, Mono или рантайм игрового движка, а при Native AOT среда встраивается в сам исполняемый файл.
Нужно ли учить .NET Framework, если начинаю с нуля?
Начинать стоит с .NET 10. Знание .NET Framework понадобится при поддержке старых корпоративных приложений, и основы (C#, CLR, BCL) там те же.
.NET Standard — это еще одна платформа?
Нет, это спецификация общего набора API. Библиотека с целью netstandard2.0 подключается и к .NET Framework 4.6.1+, и к современному .NET.



