Могу ли я иметь глобальные определения препроцессора в библиотеке C #? - PullRequest
6 голосов
/ 29 января 2012

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

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

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

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

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

Ответы [ 4 ]

5 голосов
/ 29 января 2012

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

2 голосов
/ 30 января 2012

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

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

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

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

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

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

2 голосов
/ 30 января 2012

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

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

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

1 голос
/ 26 апреля 2018

Использование GUI

  1. Открыть проект в Visual Studio
  2. Щелкните правой кнопкой мыши файл проекта в обозревателе решений и перейдите в свойства
  3. Перейдите на Build tab и убедитесь, что вы выбрали All Configurations в раскрывающемся списке конфигурации
  4. Убедитесь, что выбрано All Platforms в Platform
  5. Введите Preprocessor Definitions, который вы хотите, в текстовое поле Conditional Compilation Symbols, разделенное точкой с запятой

enter image description here

К файлу проекта

  1. Открыть файл проекта в текстовом редакторе
  2. Скопируйте и вставьте этот код в конец существующего PropertyGroup

    <PropertyGroup Condition="'$(VariableName)'=='VarableValue'"> <DefineConstants>PDEF1;PDEF2;PDEF3</DefineConstants> </PropertyGroup>

  3. Если вам не требуется добавлять условие, удалите Condition="'$(VariableName)'=='VarableValue'" part

  4. Сохраните файл проекта и откройте из Visual Studio

От: https://codeketchup.blogspot.sg/2018/04/how-to-add-project-level-preprocessor.html

...