Why is it so easy to decompile .NET IL-code into source code, compared to decompiling native x86 binaries? (Reflector produces quite good source code most of the time, while dec
I think you've got the most important bits already.
As you say, there's more metadata available. I don't know the details of what is emitted by a C or C++ compiler, but I suspect far more names and similar information are included in IL. Just look at what the decompiler knows about what's in a particular stack frame, for example - as far as the x86 is concerned, you only know how the stack is used ; in IL you know what the contents of the stack represent (or at least, the type - not the semantic meaning!)
Again, as you've already mentioned, IL is a higher level abstraction than x86. x86 has no idea what a method or function call is, or an event, or a property etc. IL has all that information still within it.
Typically C and C++ compilers optimise much more heavily than (say) the C# compiler. This is because the C# compiler assumes that most of the optimisation can still be performed later - by the JIT. In some ways it makes sense for the C# compiler not to try to do much optimisation, as there are various bits of information which are available to the JIT but not the C# compiler. Optimised code is harder to decompile, because it's further away from being a natural representation of the original source code.
IL was designed to be JIT-compiled; x86 was designed to be executed natively (admittedly via micro-code). The information the JIT compiler needs is similar to that that a decompiler would want, so a decompiler has an easier time with IL. In some ways this is really just a restatement of the second point.