I have done in practice a lot coding with both - native code - C++ - also known as unmanaged and managed code - C#. I m still not sure why C# was invented in first place - there are a lot of improvement to developer of course, but there are quite many hidden rocks behind C# architecture.
To my best understanding a lot of Microsoft professional developers received a task to make C# to happen, and like normally goes with any new platform - developers got overexcited about their technology.
First attempt was of course to claim that "we are doing right things", and everyone else is doing it wrong - I guess "unmanaged" term appeared because of that. It s like we have here "managed" code and something that was not designed properly - "un"-something. :-)
Unmanaged resources like file handles, network connections, database connections are managed for quite long time already - if you terminate process, it will close all file handles.
On C++ you have malloc, free, on C# you have new (or gcnew), but then you re fighting with problems of what references what, why this object won t go away from memory, what is eating ram - and most of answers to those questions becomes quite difficult to answer.
Constructor / destructor got replaced with finalizers, destructors, disposable objects, where it s relatively difficult to test what gets invoked, in which order, and did you remember to release all resources ? "Oh we are managed, but we don t know how to manage these objects..." :)
C# is fun for as long as it s small and simple application - after you add there 3d objects, and super huge amount of allocations, a lot of functionality, compilation starts to become slow, and you re not satisfied with C# anymore and thinking about going back to C++.
On quite many forums you can probably find some debates about - is C# or C++ better / faster / easier - and most of people try to protects using at all costs C#. Reality is that it s over-complex, over abstracted and too heavy monster, and noone can control it anymore.
Intermediate language (IL) - represents one additional abstraction layer between source code and executable code (assembly), which makes it more difficult to optimize and boost your program.
But I m not big fan of C++ either - language complexity with pointers, references and objects / classes themselves does not make C++ easier to code or easier to learn.
Basically when you construct new language - you need to take into account target language infrastructure ( low level assembly + smooth integration with C++ code and high level code improvements - easy to use, to easy understand, easy to develop, easy to maintain, and improve).
Creating more "words" in theory might make language richer - you can express yourself using less text, and more efficiently, but again this does not prevent pollution of language itself (like IDisposable).
I m intentionally comparing programming language with natural language, because I m writing now answer in natural language, and it s more native to me than programming language. Programming language however is better structured than natural and does not have 2016 years of history.
2 - finalizer / dispose - have read this chapter at least 5 times, but still don t understand it. I m typically creating one function (close) and calling it from both functions - from finalizer - and from dispose. Why to bother trying to understand something that is not important.
My recommendation to you is anyway - try everything in code - how it looks like, how it feels like. Books tends to become something similar to Bible - they drag you into religion, which you don t want to be in necessarily.