What are the limitations of C#?

A programmer cannot do low-level things like interacting directly with hardware through drivers and firmware.

It does not come with an independent compiler that can straightforwardly interpret the maximum levels of language to the underlying hardware architecture of a pure assembler. It uses its byte code and the JIT compiler that is hugely incorporated into the .Net framework and is the backbone of the .Net structure as a go-between to the machine code in the place of communicating directly with the hardware.