C# 预处理器指令可以嵌套吗?

5

我做了一些谷歌搜索,但没有找到任何关于预处理器指令嵌套的正面声明。我想要做类似这样的操作:

#if FOO
// do something
#if BAR
// do something when both FOO and BAR are defined
#endif 
#endif

我知道我可以像下面这样做,但只是想知道。
#if FOO && (!BAR)
#elif FOO && BAR
#endif

(编辑)实际上,我在我的代码中已经使用了一个更复杂的嵌套语句,但它并没有按照我的预期工作。因此,我很好奇是否有官方对此的解释。


1
我在想官方对此的立场,但在C#语言教程中找不到任何评论。 - wecky
2
文档中没有关于嵌套的说明,所以我认为这个问题是合理的。 - Lasse V. Karlsen
1个回答

8
是的,它们可以嵌套。
#define A
#define B

void Main()
{
#if A
#if B
    Console.WriteLine("A and B");
#else
    Console.WriteLine("A and not B");
#endif
#else
#if B
    Console.WriteLine("B and not A");
#else
    Console.WriteLine("neither A nor B");
#endif
#endif
}

输出:

A and B

这里有一个.NET Fiddle供您尝试:https://dotnetfiddle.net/oUuTN9
您可以分别注释掉顶部的两行内容以获取不同的结果,例如:
#define A
// #define B

输出:

A and not B

这里是加了缩紧的同样代码,使其更加清晰,但我不会像这样缩排代码。在我看来,过度使用条件指令是一种编码味道。

#define A
// #define B

void Main()
{
    #if A
        #if B
            Console.WriteLine("A and B");
        #else
            Console.WriteLine("A and not B");
        #endif
    #else
        #if B
            Console.WriteLine("B and not A");
        #else
            Console.WriteLine("neither A nor B");
        #endif
    #endif
}

谢谢,我想使用它来真正从可执行文件中排除代码,以用于不同软件版本(售价不同)。但很快就变得复杂了。我只是惊讶地发现在C#语言教程中找不到任何关于它的积极说明。 - wecky
另一种处理方式是为不同版本创建不同的程序集,并仅将正确的程序集与每个版本捆绑在一起。 - Lasse V. Karlsen
或者,使用许可证或标志使代码不可用。 - Lasse V. Karlsen
使用标志,代码仍将存在于可执行文件中。希望防止这种情况发生。 - wecky
然后,不同的程序集是一种更清晰的方式。如果你非常依赖于依赖注入,那么我会创建一个包含所有接口的程序集,让应用程序的其余部分可以使用它,然后再创建不同的程序集来实现这些接口,以便您可以为软件的不同版本选择正确的实现。 - Lasse V. Karlsen
感谢您关于依赖注入的建议。我曾经考虑过,但由于项目非常成熟和复杂,在这个时候重构它并不是一个可行的选择。 - wecky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接