【问题标题】:Conditional compilation based on constants?基于常量的条件编译?
【发布时间】:2020-06-09 12:48:10
【问题描述】:

是否可以根据类中定义的一些常量值有条件地编译类和方法,例如我想要类似的东西。

public enum BuildMode : int {
    One = 1,
    Two = 2,
    Three = 3
}

public class BuildConfig {
    // I will change this line, based on what build I want
    public const BuildMode Mode = BuildMode.One;
}

public class SomeClass {
   #if BuildConfig.Mode == BuildMode.One
       public void SomeMethod() { /* Implementation one */ }
   #elif BuildConfig.Mode == BuildMode.Two
       public void SomeMethod() { /* Implementation two */ }
   #elif BuildConfig.Mode == BuildMode.Three
       public void SomeMethod() { /* Implementation three */ }
   #endif
}

显然我知道一般情况下 C# 中的条件编译是如何完成的,我想根据类中的常量值进行条件编译,而不是基于预处理器定义。知道很多编译时的东西都使用常量(例如 Guid 属性),有没有办法根据类常量有条件地编译方法/类?有一个 Conditional 属性,但它似乎也只适用于定义。

我有一个具有多种构建模式的复杂项目,我想让其他人更轻松地构建我的项目。例如,我需要在一个设置上拥有 3 种不同的模式(可能更多),在另一种设置上拥有 2-3 种不同的模式。所以为了让其他人更容易编译我的项目,我需要有 3 * 3 = 9 个不同的预处理器定义和 9 个不同的 csproj 文件。如果我需要添加更多设置/模式/常量,这个故事并不能真正扩展。对于将编译我的代码但以前从未见过的人来说,这可能会变得非常混乱。至少编译器会对常量进行类型检查,因此不太可能搞砸。

显然,我可以构建代码以支持所有配置常量的变体,并在运行时基于它们调用代码,但我想进行优化,以便不会编译未使用的代码。

【问题讨论】:

  • 好问题。我不认为这是可能的。如果您在问题中添加 why 您想避免“经典”条件编译(即,通过将常量定义为预处理器定义),这可能会有所帮助,以便人们可以为您的潜在问题提出替代解决方案.
  • 我认为预处理是在编译之前完成的,并且在编译期间存在 const 信息。所以这是不可能的。让我们等待专家解答
  • @Heinzi 好建议
  • @Heinzi,添加了一些说明。

标签: c# .net


【解决方案1】:

没有 -

C# 不会评估 #if preprocessor directive 中的表达式 - 它只会查看符号是否已定义:

当 C# 编译器遇到 #if 指令,最后是 #endif 指令时,它会编译指令之间的代码只有定义了指定的符号。与 C 和 C++ 不同,您不能将数值分配给符号。 C# 中的#if 语句是布尔值,仅测试符号是否已定义。

(强调)

所以做你想做的事情的正确方法是:

public class SomeClass {
   #if BUILD_MODE_ONE
       public void SomeMethod() { /* Implementation one */ }
   #elif BUILD_MODE_TWO
       public void SomeMethod() { /* Implementation two */ }
   #elif BUILD_MODE_THREE
       public void SomeMethod() { /* Implementation three */ }
   #endif
}

符号可以在该代码文件中定义,也可以通过 CSC.EXE 的命令行参数定义。

【讨论】:

  • 有没有办法让 MSBuild 解析我的 BuildConfig 类并生成正确的定义?
猜你喜欢
  • 2019-06-19
  • 2012-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-02
  • 2011-03-06
相关资源
最近更新 更多