There are many parts.
There is the language. The language says that a garbage collecting memory manager is used. When you call new an object is created, and when it has no more references the object is cleaned up. The details of how that gets implemented internally is left up to the implementation.
Then there is the compiler and execution environment implementation. Currently there are two major implementations, MS and Mono. The language gets compiled into the virtual machine's intermediate language, but that is not a requirement. It could be compiled to any target, even directly to machine code if you wanted to build a compiler for that. Just like any compiled code, the details of how that works are up to the implementation. It could be part of a virtual machine and rely on the virtual machine to allocate it. It could be done through a third-party library behind the scenes. It could be managed in raw machine code. That is not specified as part of the language, but is part of the implementation.
The .net framework has a huge collection of classes and functions. Some of those functions are designed to control Microsoft's runtime environment, including the garbage collector. This is also not part of the C# language, but is a piece of library functionality. These libraries may or not be present, and are not required by the language.
It is not so different from any language, including C++.