MANAGED CODE vs UNMANAGED CODE
If you are coming from a scripting language background like python or bash into certain technologies like dotNet, one of the concepts that may seem confusing is the concept of managed codes and unmanaged codes.
Unlike scripting languages which require just an interpreter to work on any host machine, languages like Java and dotNet require specific runtimes on the host machines to be able to execute the codes written on any other machine. Thus, during development, the codes written target the runtime and not the host machines.
Managed codes are those codes that target runtime. These sets of codes are usually compiled by the compiler not for the host machine, but in an intermediate language that the target runtime on the host machine can understand.
On the other hand, unmanaged codes are codes that cannot be hosted directly by the runtime. These sets of codes are usually compiled for the specific host machine and may not be able to run a different host machine unless they are recompiled for that machine.
In the dotNet ecosystem, the dotNet runtime serves as an intermediary between the various languages that the dotNet framework supports such as C#, F#, and VB.Net. Codes written in the various languages are not compiled directly into machine executable codes, instead are first compiled into a Common Intermediate Language (CIL). This CIL is the version of the code that is targeted to the dotNet runtime. The dotNet runtime will eventually convert this at runtime into host machine-specific code. That is why it is referred to as managed codes.
Managed codes are popular with legacy languages like Java and C# that target different host machines thus removing the hassle of coding for different platforms from the developers as they write managed codes for the runtime and the runtime handles the rest.