我可以在C#库中使用全局预处理器定义吗?

时间:2012-01-29 13:13:12

标签: c# .net c-preprocessor

在C#中,您可以使用类似于 C / C ++语法的宏进行条件编译。这将使以下情况发生:

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

我需要在C#库项目的专用文件中定义一些宏,一旦定义,我需要这些宏在整个库中可见。问题是上面的代码只适用于单个文件。

我知道解决此问题的另一种方法是将宏添加到构建命令中。这将负责为整个.dll定义宏,并且我将#if - #else检查在库中的任何地方工作。这种方法的问题是我希望能够轻松维护宏。将它们放在项目内的文件中将是完美的。我也想在里面发表一些评论,以便我知道每个宏在做什么。如果我必须将宏作为构建参数传递,这将不适用。另一个原因是能够通过简单地评论和检查行为来打开/关闭宏。

有没有一个体面的方式来达到我的要求?我宁愿不处理任何构建自动化工具,如MSBuildNAnt或类似的东西,如果没有其他办法可行,我会很感激您认为更好的选择。

4 个答案:

答案 0 :(得分:5)

您可以使用Project + Properties,Build选项卡,“条件编译符号”设置为整个项目#define它们。这将在项目文件中设置<DefineConstants>元素。使用msbuild覆盖此属性,方法是给它/ property:DefineConstants =“MYMACRO”命令行选项。

答案 1 :(得分:2)

C#“预处理程序”指令与C预处理程序指令的工作方式不同。对您而言最重要的区别是没有相应的#include。在正常情况下不需要它,因为C#没有(或需要)头文件。我不认为你想要什么是可能的,除非你以某种方式创建自己的预处理器或用#define s读取文件并将它们变成msbuild的参数。

但我认为使用更多面向对象的方法会更容易:将不同的方法封装到类中并使用它们。要指定要使用哪一个,可以使用依赖注入。这意味着您必须与您的图书馆一起发送DI库,但我认为这是值得付出的代价。

此外,这种方法可以缓解条件编译的问题:指定不同的符号集可能会以意想不到的方式破坏构建。

答案 2 :(得分:2)

我还建议将宏放在项目设置(csproj文件)中,如@Hans Passant建议的那样。

如果您需要记录定义,可以在解决方案中添加一个文档文件,说明设置的含义。

如果没有太多变体,您可以为每个变体定义一个新的项目配置。这将允许您为每个变体预先配置必要的#defines列表,然后只需从工具栏中的配置组合框切换它们。如果要暂时禁用一个选项,可以复制当前配置并删除#define,然后在测试后删除配置。

我可以建议的下一个选项是“更容易”(通过将设置和文档组合成您建议的单个文件)将使用简单的文本文件(设置+注释)来配置项目,并花15分钟编写一个快速的c#应用程序来读取此文件,并将其包含的设置写入.csproj文件 - 它只是XML,所以应该是一个简单的应用程序来编写。您将能够轻松调整此文件并运行更新程序应用程序以更新项目设置。如果您经常这样做,请花30分钟时间添加一个带复选框的用户界面,以便更轻松地选择设置。

你所描述的概念听起来很奇怪。库的重点通常是你有一个标准化的代码块可以被许多客户端共享,所以改变这些类型的定义来重新配置整个库并不是我希望经常需要做的事情。 。也许你有充分的理由,但可能值得回顾为什么你需要解决这个#define问题。

(例如,如果您有许多客户需要不同的“库”变体,最好的方法是使用配置(如上所述),以允许您在批量构建中构建所有需要的变体。如果您只是尝试了很多不同的算法/技术然后你可以重新设计库的块,以便你可以限制大多数#defines对单个.cs文件的影响,所以它们不再需要是全局的吗?也许库不应该在一个DLL中,或者需要一个插件架构来允许您选择库中包含的“模块”。

答案 3 :(得分:1)

使用GUI

  1. 在Visual Studio中打开项目
  2. 右键单击解决方案资源管理器中的项目文件,转到属性
  3. 转到Build tab并确保在配置下拉列表中选择All Configurations
  4. 确保选中All Platforms下拉列表中的Platform
  5. 在以{分号分隔的Preprocessor Definitions文本框中键入所需的Conditional Compilation Symbols
  6. enter image description here

    到项目文件

    1. 在文本编辑器中打开项目文件
    2. 将此代码复制并粘贴到现有PropertyGroup

      的末尾

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

    3. 如果您不需要添加条件,请删除Condition="'$(VariableName)'=='VarableValue'"部分

    4. 保存项目文件并从Visual Studio
    5. 打开

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