In practice, I encoded a lot like with native code - C ++ - also known as unmanaged and managed code - C #. I'm still not sure why C # was invented in the first place - for developers, of course, there are many improvements, but behind the C # architecture there are quite a few hidden stones.
To my best understanding, many professional Microsoft developers have been given the task of making C #, and, as usual, comes with any new platform - the developers are overloaded with regard to their technology.
The first attempt, of course, was to say that "we are doing the right thing," and everyone else is doing it wrong - I think, because of this, an "uncontrollable" term appeared. It looks like we have “managed” code and something that was not designed properly is “un” -something :-)
Unmanaged resources, such as file descriptors, network connections, database connections, have been managed for quite some time - if you complete the process, it will close all file descriptors.
In C ++ you have malloc, for free, in C # you have a new one (or gcnew), but then you are struggling with the problems of linking what, why this object will not disappear from memory, what ram is - and most of the answers these questions are becoming quite difficult to answer.
The constructor / destructor is replaced by finalizers, destructors, disposable objects, where it is relatively difficult to check what is caused, in what order, and have you forgot to free all resources? "Oh, we succeeded, but we don’t know how to manage these objects ..." :)
C # is fun as long as it is a small and simple application - after you add 3D objects and a super huge number of distributions there, a lot of functionality, compilation will start to slow down and you are no longer satisfied with C # and think about returning in C ++.
In quite a few forums, you can probably find some debate about - is C # or C ++ better / faster / easier - and most people try to defend using any of these C #. The reality is that it is too complex, over an abstract and too heavy monster, and no one else can control it.
Intermediate language (IL) - represents one additional level of abstraction between the source code and the executable code (assembly), which makes it difficult to optimize and speed up your program.
But I'm also not a big fan of C ++ - the complexity of the language with pointers, links, and objects / classes does not simplify C ++ code or is easier to learn.
In principle, when you are building a new language, you need to take into account the infrastructure of the target language (low-level assembly + smooth integration with C ++ code and high-level code improvements), easy to use, easy to understand, easy to develop, easy to maintain, and improve).
Creating more “words” in theory can make the language richer - you can express yourself using less text and more efficiently, but again this does not prevent the language itself from being polluted (for example, IDisposable).
I intentionally compare a programming language with a natural language, because now I write the answer in a natural language, and it is more native to me than a programming language. However, a programming language is better structured than natural, and has no 2016-year history.
2 - finalizer / dispose - read this chapter at least 5 times, but still do not understand. Usually I create one function (close) and call it from both functions - from the finalizer - and from the order. Why try to understand something that is not important.
My recommendation to you anyway - try everything in the code - how it looks, how it looks. Books, as a rule, become something similar to the Bible - they push you into a religion in which you don’t want to be.