【问题标题】:Compile time checking of conditional compilation symbols in C# (see example)?C# 中条件编译符号的编译时间检查(参见示例)?
【发布时间】:2010-09-28 02:57:27
【问题描述】:

在 C/C++ 中,您可以执行以下操作:

#define IN_USE      (1)
#define NOT_IN_USE (-1)

#define USING( system ) ( 1 / (system) == 1 / IN_USE )

然后:

#define MY_SYSTEM  IN_USE

#if USING( MY_SYSTEM )
    <my_system impl>
#endif

这种设置意味着:

  • 所有条件编译符号都必须定义为 IN_USE 或 NOT_IN_USE。

  • 我可以将它们全部放在一个(或几个)头文件中,然后轻松打开/关闭它们,看看有哪些条件编译符号。

  • #if USING(MYSYSTEM) 之类的错字由于 div by 0 而不是静默编译出来而被编译器捕获。

在 C# 中可以做到这一点吗?是否有其他最佳实践方法可以达到相同的效果?

我意识到在 C# 中您可以通过在项目设置中设置它们并使用 #if 来进行条件编译,但我不喜欢不必明确未定义的事实。这就是项目设置中有“DEBUG”和“TRACE”复选框的原因。如果它们不在那里,您将不知道可以打开它们。

【问题讨论】:

    标签: c#


    【解决方案1】:

    C# 不允许给预处理器符号,但您可以使用#define#ifdef/#endif。通常预处理器符号实际上是在项目级别定义的 项目属性而不是代码。

    您可能还对ConditionalAttribute 感兴趣,如果相关的预处理器符号不存在,它允许调用 以它装饰的方法被省略。 (该方法本身仍在构建中;它只是确定调用是否实际发生。)

    如果您想要实际的常量值,您可以改用conststatic readonly 字段。

    【讨论】:

    • 看起来他也在寻找 C++ 宏类型能力。不过,我想不出一种方法来解决这个问题。
    • 是的,我就是这样做的。但是,我要解决的主要问题是我错误地键入“#if DEBG”而不是“#if DEBUG”的情况。一个不错的选择是能够查看所有可能的条件编译符号是否正在使用。
    【解决方案2】:

    C# 没有预处理器,但编译器足够聪明,如果你给它一个常量作为 if() 条件,它会适当地发出/不发出代码,产生相同的效果。

    // in Conditionals.cs
    public static class Conditionals
    {
         public const bool MY_SYSTEM = true;
    
    }
    
    // In SomeOther.cs
    if (Conditionals.MY_SYSTEM)
    {
    //  <my_system impl>            
    }
    

    【讨论】:

      【解决方案3】:

      C# 没有 c 预处理器。 它确实让您拥有可以设置为已定义或未定义的项目范围或文件范围的#define。您只能在 #if/#else 块中使用它,并且您的测试仅限于存在/不存在。

      因此,在您的情况下,在 VisualStudion 的项目设置中,在 Build 下,条件编译符号框中将包含 MY_SYSTEM。

      一般来说,如果可能的话,您希望围绕类定义而不是预处理器诡计来考虑您的模块。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-09-29
        • 2023-03-30
        • 1970-01-01
        • 1970-01-01
        • 2018-01-21
        • 1970-01-01
        • 2010-10-03
        相关资源
        最近更新 更多