Какой код считается неуправляемым в .NET
Что проверяют
Понимаете ли вы, где заканчивается ответственность CLR, и не путаете ли три разных понятия: неуправляемый код, неуправляемые ресурсы и unsafe. Следом обычно спрашивают, как вызвать нативную функцию и как правильно освободить нативный хэндл.
Как отвечать
Управляемый код компилируется в IL и исполняется под CLR: JIT, сборщик мусора, проверки границ массивов, исключения. Неуправляемый код это машинный код, про который среда ничего не знает: нативные библиотеки .dll и .so на C, C++ или Rust, Win32 API, COM-компоненты, системные библиотеки ОС. Память там выделяется и освобождается вручную, GC её не видит.
Как .NET с ним работает:
- P/Invoke:
[DllImport]или, начиная с .NET 7,[LibraryImport], который генерирует код маршалинга на этапе компиляции и лучше дружит с trimming и Native AOT; - COM interop: вызовы COM-объектов через RCW, актуально на Windows;
- C++/CLI: смешанные сборки, только под Windows;
- нативная память из C#:
Marshal.AllocHGlobalилиNativeMemory.Alloc, освобождать её нужно самим.
Отдельно про ресурсы: файловый дескриптор, сокет, хэндл окна принадлежат ОС. Их заворачивают в SafeHandle, а наружу отдают через IDisposable и using. Финализатор это страховка на случай, когда Dispose не вызвали, а не основной механизм.
Риски тоже стоит назвать: утечки нативной памяти не видны в дампе управляемой кучи, падение в нативном коде обычно роняет весь процесс и catch его не поймает, а маршалинг строк и структур стоит времени на каждом вызове.
Где спотыкаются
Называют unsafe-код неуправляемым. Это управляемый код: он компилируется в IL и живёт под GC, просто работает с указателями без проверок. Ограничение where T : unmanaged тоже не про нативный код, а про типы без ссылочных полей.
Считают, что Native AOT делает приложение неуправляемым. Код компилируется в машинный заранее, но рантайм, GC и исключения никуда не деваются.
Путают неуправляемый ресурс с неуправляемым кодом и называют FileStream неуправляемым кодом. Сам класс управляемый, неуправляемый у него только хэндл внутри.