Простыми словами.
1. Код на языке программирования может компилироваться не только в нативный код ОС, но и в байт код исполняющей машины. Исполняющая машина же может быть доступна для разных ОС. В этом и есть ее смысл, чтобы один и тот же исполняемый файл мог запускаться на разных ОС.
2. Проект может состоять не только из ваших файлов, но и из заранее скомпилированных библиотек (очевидно).
3. Всеобъемлющий набор из исполняющей машины, компилятора вашего языка (и возможно других языков) в байт код этой исполняющей машины, и кучи библиотек (+ возможно некоторых других инструментов разработки) принято называть фреймворком.
Скажем еще проще: фреймворк это огромный набор библиотек и инструментов разработки.
В нашем конкретном случае язык это C#, а фреймворк это .NET.
Но есть и другие фреймворки, например Java (использует язык Java) или .NET Core (тоже использует C#).