基于常量的条件编译?

时间:2020-06-09 12:48:10

标签: c# .net

是否可以基于类中定义的某个常量值有条件地编译类和方法,例如,我想拥有类似的东西。

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属性,但似乎它也只适用于define。

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

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

1 个答案:

答案 0 :(得分: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的命令行参数来定义符号。