Введение в директивы компилятора C#
Строка, которая начинается с #, адресована компилятору.
Программа её не выполняет. Компилятор читает директиву до
того, как превратит исходник в код сборки, и решает, какой
фрагмент оставить.
Условная компиляция как раз про этот выбор. Один и тот же файл может содержать отладочный вывод, который попадает только в отладочную сборку. В выпускной сборке этих строк нет вообще, а не «вызов, который ничего не делает». Текст файла при этом не переписывается: отдельной подстановки кусочков текста, как в макросах, в C# нет.
Также компилятору говорят, включать ли проверку пустых ссылок, вставить ли предупреждение или ошибку сборки и как свернуть кусок файла в редакторе. Раздел про эти указания сборке.