在C#中定义编译器指令

7
在C语言中,我可以使用以下方式声明编译器指令:
#define MY_NUMBER 10

然而,在C#中,我似乎只能这样做:
#define MY_NUMBER

在这种情况下,显然是无用的。

我的做法正确吗?如果不正确,有没有人能够建议一种在命名空间或解决方案级别实现此功能的方法?我想过可能创建一个静态类,但这似乎对于一个值来说过于复杂。

6个回答

6

是的,这是正确的。

以下是MSDN文档中的引用:

预处理指令提供了条件地跳过源文件的部分内容、报告错误和警告条件以及划分源代码的不同区域的能力。术语“预处理指令”仅用于与C和C++编程语言保持一致。在C#中,没有单独的预处理步骤;预处理指令作为词法分析阶段的一部分进行处理。

因此,你不能像在C和C++中定义编译器常量。

相关资源:


5
很多其他的答案建议使用public const字段。但请注意,public const将会被编译进引用它的程序集中,如果您改变了const的值,那么不仅需要重新编译该字段所在的程序集,还需要重新编译所有引用它的程序集。
如果您不能确定该值永远不需要更改,那么public static readonly字段是一个更好的选择。

谢谢,这真的很有帮助!我以前不知道这个。 - Robert Fraser
@RobertFraser 是的,枚举类型永远不应该改变,它们只是带有编译器魔法的整数常量。(来源) 更重要的是,这样的破坏性更改在运行时很难被捕获,几乎没有被编译器捕获的机会。使用您的枚举/常量的程序集可能仍然可以运行,但可能开始出现随机行为。因此绝对不能更改公共常量。无法预测这种更改可能会造成多大的破坏或问题何时被发现!如果有疑问,请使用readonly。 - AnorZaken
@AnorZaken 我忍不住觉得那是一个设计错误。这甚至不是一种优化,因为JIT可以像编译器一样做常量折叠。哎,事后诸葛亮。 - Robert Fraser
@RobertFraser Eric Lippert很久以前在这里发表了一条评论,他称枚举实现是C#中最大的设计错误。但原因并不是由于它是一个常量,而是a) 它是一个丑陋的 hack,模仿了来自C++的旧枚举类型(框架中的所有枚举代码都非常奇怪,并污染了整个类型系统),b) 因为它具有两个不同的目的-命名常量和标志-所以应该将其拆分为两个单独的类型(就像Java中的那样)。个人认为常量不是一个错误,但也许编译器应该在公共 const 时警告您。 - AnorZaken

3

您可以定义一个常量或静态只读变量,如果您希望它有条件地存在,您可以将其包装在 #if 指令中。

#if DEBUG
private const int MY_NUMBER = 10;
#else
private const int MY_NUMBER = 20;
#endif

3

没错,你说得对。 constreadonly 是你唯一的选择。


1

使用公共常量


据我所知,

C#不使用预处理器定义来执行代码替换,因此您必须使用常量。

这应该可以解决问题:

public const int MY_NUMBER = 10;

1

您可能还想检查枚举,例如

enum Numbers
{
    Nothing = 0,
    Dads = 5,
    My = 10,
    LittleJims = 25
}

因此,你可以使用Numbers.My代替C语言中的MY_NUMBER。


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