【问题标题】:#define directive purpose#define 指令目的
【发布时间】:2012-07-25 23:48:06
【问题描述】:

#define指令在C#中的用途和好用处是什么?

关于这个主题的问题已经很少,但我不需要答案。他们只举例说明它是如何工作的。但我需要更深入的解释:它为什么存在以及使用它的好方法是什么(如果有的话)。

基本上我知道如何使用它,但对我来说用法看起来很奇怪。我们来看例子:

#define DEV

#if DEV
Console.WriteLine("Development trace log message");
#endif

对我来说这与使用带有项目定义的条件编译符号的#if 条件构建完全不同。如果我们使用项目定义的符号,它会附加到项目构建配置中,我们可以使用构建配置来管理构建所需的代码(并从构建中排除)。所以代码

#if DEBUG
Console.WriteLine("Debug log message");
#endif

对我来说很好。但正如我所说,它与使用#define 指令完全不同,因为它是可管理的。 我是否正确,第一个示例只能在每次构建时手动注释/取消注释 #define 行?如果是,它是不可管理的,难以维护,我认为 #define 的这种用法是非常糟糕的做法,并且在语言中根本不存在。

我可以想象在#if 语句中使用#define/#undef。类似的东西

#if DEBUG
#if CLIENT1
#define TEST_CLIENT1
#endif
#endif

#if TEST_CLIENT1
connectionString = "Some specific test connection" //I know this is bad practice even in conditional. Only for example purpose.
#elif
//Read connection from config
#endif

#if UNITTESTS
#undef TEST_CLIENT1
#endif

#if TEST_CLIENT1
Console.WriteLine("Some message");
#endif

抱歉,这个例子太复杂了,但这至少是我觉得有用的东西。虽然我不会以任何方式编写这样的代码 =)。 #define 有什么好的用法吗?

PS:我 5 年来从未使用过 #define 自己,也没有意愿这样做,但我得到了一个支持项目,其中有许多奇怪的定义,甚至以奇怪的方式命名。这些定义通常放在文件的顶部,就像我在这里的第一个例子一样。而且我不知道如何维护这段代码。

【问题讨论】:

    标签: c# c-preprocessor conditional-compilation


    【解决方案1】:

    '#define' 存在是因为人们期望它存在。 :) 出于您的目的(例如大型项目),在项目中保留预处理器符号可能更有意义。对于快速调试或其他目的,#define 可能是最佳选择。此外,#define 允许对符号进行细粒度(文件级别)控制。

    想象一下,您有一个庞大的代码库和一个给您带来麻烦的模块。出于性能原因,您可能希望仅在要启用跟踪/调试的单个文件中使用“#define TRACE”或“#define DEBUG”。

    【讨论】:

    • 恐怕定义 DEBUG 符号不会使您能够调试代码。从你的话中,#define 应该只用于项目稳定阶段,用于快速修复和日志。但我不想相信这种结构的存在只是因为这个原因 =)
    • 这真的是一个完整的东西。已经习惯了 C/C++ 预处理器的人会期望(在 C# 允许的范围内)有类似的体验。这意味着能够通过命令行或代码文本添加预处理器指令。能够同时做到这两点意味着开发人员有更多的工具可以使用。例如,假设你有一些使用 CodeDom 编译器的服务,你只能给它文本来编译。无论出于何种原因,您都可能希望在该代码中使用#if,这意味着您需要#define。
    【解决方案2】:

    除了没有它,我看不到任何正当理由,#IF 语句将不存在。

    当您在编译器上使用/define 指令定义项目级前置条件变量时,它真正要做的就是在代码中添加#DEFINE

    我认为这使它易于管理,但不能使用/define 语句在代码中手动设置它。

    另一个用处是可读性和范围。项目定义语句适用于项目,#DEFINE 级别语句仅适用于一个文件。这有助于保持事物的组织性、可读性并阻止可变问题。

    【讨论】:

    • 对不起,我不明白你在这里的可编辑性和范围是什么意思。在文件中定义符号与删除所有不匹配条件的代码并删除带有此符号的#if 条件相同。使用它的唯一方法是在调试期间减少评论/取消评论。但是为什么这应该出现在发布代码中?在可管理下,我的意思是能够改变它,在 VS 中运行不同的构建脚本或不同的构建配置。
    • @OleksandrPshenychnyy 很抱歉,如果答案不是很清楚,我同意它在当前形式下非常难以管理。将它列在文件中的唯一好处是您知道它在那里,您可以在文件顶部阅读它并知道它支持这些变量。我认为你可以用定义语句做的大部分事情都可以用管理良好的代码来做。您可能需要一两个额外的 OP,但如果您真的真的想要微优化,那么它会很方便,但如果您需要优化这么多,C# 可能不是选择:D
    • 谢谢。优化可能是该项目中考虑的最后一件事=)。但是,如果您同意 #define 不是一个好习惯,我不明白为什么它甚至存在于 C# 语言中。当我们使用 VS prject 条件符号时,您说编译器将它放在代码中(在每个文件中??)。实际上这可能是原因,但我认为禁止开发人员用代码编写它是可能的。
    猜你喜欢
    • 2011-02-17
    • 2011-09-11
    • 2021-12-30
    • 2019-03-25
    • 2021-12-31
    • 2018-12-18
    • 2015-03-04
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多