C# by default doesn't generate native code. C# generate CIL (Common Intermediate Language), which only gets turned into native code at runtime by the JIT (Just in time compiler).
That being said, it is also possible to generate a native image (using ngen) to transform CIL into native code for a specific machine. But that approach is the exception more than it is the norm.
I am pretty sure ngen doesn't create native code in the sense that it doesn't create a windows executable. All it does is the same as the JIT but does it up front (for the target platform). In other words it still generates something the runs inside the CLR.
It does generate native code. What else do you think is what runs at runtime? .NET never has been interpreted (apart from Micro) so you either have the JIT or ngen and both result in the bytecode translated to native code prior to running. That it still calls into the CLR for things like object allocation, garbage collection, etc. doesn't change anything. You can do the same from C++ if you want.
You're right, it's basically skipping the JIT step for better performance for managed apps at the cost of higher initial load time (e.g. more to read from disk).