Для некоторых проблем проще написать программу, которая может генерировать программу, которая решит актуальную проблему. Одна область, где это особенно полезно, - это создание синтаксических анализаторов для компиляторов.
В других случаях вы можете генерировать код на лету, который можно адаптировать для обеспечения оптимальной производительности при работе с конкретным типом данных, о свойствах которого вы только что узнали во время выполнения, отражая его метаданные. Одним из примеров, который я могу привести для этого, является мой Modelshredder проект. В основном он берет все поля и свойства объекта и упаковывает их значения в массив объектов.
Моим первым подходом к этой проблеме было ручное кодирование MSIL с использованием Reflection.Emit
. Второй подход был немного более динамичным и основывался на деревьях выражений, которые можно эффективно создавать и компилировать во время выполнения, чтобы обеспечить ту же функциональность, что и моя инъекция MSIL, написанная вручную. Вы можете увидеть, что реализовано в стволе MoreLinq (просто посмотрите на сайт Modelshredder, для этого есть ссылка). Наличие Compiler as a Service фактически позволило бы мне повысить уровень абстракции и создать код C #, который затем будет скомпилирован в MSIL.
Обоснование языков, специфичных для предметной области, уже сделано, и я думаю, что такой императивный язык, как C #, не подходит для сценария «командной строки», а скорее для сценариев большего размера.
Существует аккуратная система make, основанная на F # DSL под названием FAKE , которая заимствует много концепций компилятора как сервиса. Аналогичные концепции используются в интерактивном окне F # (так оно называется?) Внутри VisualStudio.