Пишите на IL, если есть необходимость.
Чтобы IL код запустить с помощью dotnet, нужно его упаковать в байт-код. Есть инструмент ilasm, который упаковывает IL в переносимый исполняемый файл (PE). Внутри PE файла, грубо говоря, происходит вызов dotnet'a, на вход которому передаётся сам PE. Ну а dotnet уже решает что с ним делать - оптимизирует, компилирует, транслирует и т.п.
Чтобы IL код запустить с помощью dotnet, нужно его упаковать в байт-код. Есть инструмент ilasm, который упаковывает IL в переносимый исполняемый файл (PE). Внутри PE файла, грубо говоря, происходит вызов dotnet'a, на вход которому передаётся сам PE. Ну а dotnet уже решает что с ним делать - оптимизирует, компилирует, транслирует и т.п.