2012-01-29 3 views
6

В C# вы можете иметь условную компиляцию с помощью макросов, аналогичных синтаксису C/C++. Это позволило бы следующее произойдет:Могу ли я иметь глобальные определения препроцессора в библиотеке C#?

#define MYMACRO 
.... 
#if MYMACRO 
//some C# code logic 
#else 
//some other C# code logic 

мне нужно определить некоторые макросы в выделенном файле в библиотеке проекта C#, и мне нужны эти макросы, чтобы быть видимым внутри всей библиотеки, когда определены. Проблема в том, что приведенный выше код работает только для одного файла.

Другим способом, который я знаю, чтобы обойти это, является добавление макросов в команду сборки. Это позаботится о том, чтобы определить макросы для всего .dll, и у меня будут проверки #if - #else, где бы я ни захотел внутри библиотеки. Проблемы с этим подходом состоят в том, что я хочу иметь возможность легко поддерживать макросы. Наличие их в файле внутри проекта будет идеальным. Я тоже хотел бы иметь некоторые комментарии внутри, чтобы я знал, что делает каждый макрос. Это не применимо, если мне нужно передать макросы в качестве параметров сборки. Другая причина заключается в том, чтобы включить/выключить макрос, просто комментируя его и исследуя поведение.

Есть ли достойный способ достичь моего требования? Я бы предпочел не заниматься любыми инструментами автоматизации построения, такими как MSBuild, NAnt или что-то в этом роде, если бы не было другого способа, я бы по достоинству оценил совет, который вы считаете лучшим выбором.

+0

Вы можете добавить файл csproj .... –

+0

Do вы имеете в виду, как строить параметры? Если это то, что вы имеете в виду, я уже говорил, что сейчас я не удовлетворен этим подходом. Если нет, я был бы рад, если бы вы поделились дополнительной информацией о том, как это сделать. Спасибо –

+0

Почему вы используете так много условных символов компиляции (это то, что они называются, они не являются «макросами»)? Возможно, есть и другой способ сделать то, что вы хотите. – svick

ответ

2

Я также советую поместить макросы в настройки проекта (файл csproj), как предлагает @Hans Passant.

Если вам требуются определенные документы, вы можете добавить файл документации в решение, объясняющее, что означают настройки.

Если вариантов не так много, вы можете определить новую конфигурацию проекта для каждого из них. Это позволит вам предварительно настроить необходимый список #defines для каждого варианта, а затем просто переключиться между ними из поля со списком конфигурации на панели инструментов. Если вы хотите временно отключить один параметр, вы можете дублировать текущую конфигурацию и удалить #define, а затем удалить конфигурацию позже, когда вы ее протестировали.

Следующая опция, которую я могу предложить сделать «проще» (объединив настройки и документы в один файл, как вы предложили), будет использовать простой текстовый файл (настройки + комментарии) для настройки проекта , и потратьте 15 минут на создание быстрого приложения C# для чтения этого файла и записи настроек, содержащихся в файле .csproj, - это просто XML, поэтому это должно быть тривиальное приложение для записи. Вы сможете легко настроить этот файл и запустить приложение updater для настройки параметров проекта. Если это то, что вы часто будете делать, потратьте на это 30 минут и добавьте пользовательский интерфейс с флажками, чтобы легче выбирать настройки.

Концепция, которую вы описываете, звучит довольно странно. Точка библиотеки обычно состоит в том, что у вас есть один стандартизированный кусок кода, который может использоваться многими клиентами, поэтому изменение этих определений для реорганизации всей библиотеки - это не то, что я ожидал бы сделать очень часто , Возможно, у вас есть веские причины, но, возможно, стоит рассмотреть , почему вам нужно решить эту проблему #define.

(например, если у вас есть много клиентов, которым нужны разные варианты «библиотеки», наилучшим подходом будет использование конфигураций (описанных выше), чтобы вы могли создавать все необходимые варианты в пакетной сборке. просто попробовав множество разных алгоритмов/методов, тогда вы можете перепроектировать фрагменты библиотеки, чтобы ограничить влияние большинства #defines только на один .cs-файл, чтобы они больше не нуждались в глобальном? Возможно, библиотека shouldn ' t быть в одной dll, или необходима архитектура подключаемого модуля, чтобы вы могли выбрать «модули», которые включены в библиотеку)

+0

Спасибо за длинный, но полезный пост. Я уже начал пересматривать свой подход с помощью директив препроцессора. Я не хочу иметь DI в любой форме в моей библиотеке, поэтому я постараюсь сделать что-то с настройкой. Ваше другое предложение для написания приложения, которое возьмет файл и добавит его в файл csproj, также может быть применено как команда pre-build, я полагаю. –

5

Вы #define их для всего проекта с Project + Properties, Build tab, «Условные символы компиляции». Это устанавливает элемент <DefineConstants> в файле проекта. Вы переопределяете это свойство с помощью msbuild, предоставляя ему параметр/property: DefineConstants = «MYMACRO».

+0

Спасибо за эту информацию, но это не совсем то, что мне нужно. Мне нужны макросы, определенные в стандартном файле C#, и все же достигайте того же эффекта, что и вы упомянули. Я начинаю верить, что это будет невозможно со стандартными возможностями VS. –

+2

Правильно, я бы не опубликовал этот ответ, если бы ваш предпочтительный подход мог работать. –

+1

Этот ответ помог мне, а не другим ответам. –

2

Директивы C# «препроцессор» не работают так же, как директивы препроцессора C. Самое важное для вас - отсутствие эквивалента #include. В обычных условиях это не требуется, потому что C# не имеет (или не требует) файлов заголовков. Я не думаю, что то, что вы хотите, возможно, если вы каким-то образом не создадите свой собственный препроцессор или не прочитаете файл с #define s и внесите их в параметры msbuild.

Но я думаю, вам будет проще использовать более объектно-ориентированный подход: инкапсулировать различные подходы в классы и использовать их. Чтобы указать, какой из них использовать, вы можете использовать инъекцию зависимостей. Это означает, что вам придется отправить библиотеку DI вместе с вашей библиотекой, но я думаю, что это стоит того, чтобы заплатить.

Кроме того, этот подход облегчил бы проблему с условной компиляцией: указание различного набора символов может нарушить сборку неожиданными способами.

Смежные вопросы