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.