我知道C#
中的#define
可以让你定义一个符号作为传递给#if
指令的表达式,并且表达式将计算为true
。在C#中使用#define的真实世界示例?
但我想不出此功能的任何实际使用中,做任何人都知道它真正的用途?
我知道C#
中的#define
可以让你定义一个符号作为传递给#if
指令的表达式,并且表达式将计算为true
。在C#中使用#define的真实世界示例?
但我想不出此功能的任何实际使用中,做任何人都知道它真正的用途?
目前根本没有一个整体很多关于它的用途。
随着#define
可以只定义常量条件编译,你通常会从构建配置控制这些。
#define
直接插入在C#源文件中的预处理器指令是非常实用的不。 你可以这样设置prepocessor变量:
#define PRO_VERSION
然后,如果你想有两个版本的应用程序(一个PRO付费版本和免费版本),你可以封装保留给PRO代码版本与prepocessor指令#if PRO_VERSION
...
#if PRO_VERSION
SomethingOnlyInProVersion();
#elif
SomethingOnlyInFreeVersion();
#endif
...
#if PRO_VERSION
public void SomethingOnlyInProVersion()
{
}
#elif
public void SomethingOnlyFreeVersion()
{
}
#endif
但是这一切都将功亏一篑。如果你想编译代码,而不PRO_VERSION您需要删除#define
,因为你不能赋值像在旧的C编译器(如#define PRO_VERSION = 0
。该指令的另一个问题是它的知名度。范围仅限于当前文件。VisualStudio中介绍了配置管理器只是为了解决这样的问题。在那里,你可以创建不同的Configurations
,每个都有自己的一套定义的符号,可以进行检查,并应用到整个解决方案或单个项目不接触的源文件。
#if DEBUG
var jwriter = new VerboseJsonWriter(0);
#else
var jwriter = new TerseJsonWriter();
#endif
第一个以一种漂亮的方式格式化JSON,包括缩进,新行上的所有内容等,以便调试时人类可读。
因此,在生产带宽优化使用和东西快速加载第二个放置在一个样样在行,没有任何空白。
这个答案没有显示使用的'#define' – 2012-04-02 07:37:36
@AndrewCooper--正如Henk Holterman的回答中已经提到的那样,这些通常是从构建过程中传递过来的。但是这仍然证明了这种符号的用途。 – 2012-04-02 07:50:09
是的,但OP没有询问符号的使用,他问我们是否会使用'#define'指令。 – 2012-04-02 12:23:10
你可以在你的代码调试记录器,你不想在你的发布代码使用,因此你应该使用#define
:
#if DEBUG_LOG
DebuggingTool.Activate();
#else
DebuggingTool.Deactivate();
#endif
而在VS 2010中,你可以生成选项卡上conditional compilation symbols
添加添加全局符号
编译时符号的最常见用法是DEBUG
,默认情况下通过调试构建配置定义,而不是使用#define
语句。在实践中,我所看到的所有编译时符号都是通过构建配置来定义的。
这主要是由于源文件在C#中的结构方式。在C++中,一些头文件(.h)通常包含很多#defines,用于像平台相关的配置。 C#不支持将文件包含到源文件中。另外,.NET的(很大程度上)平台独立特性消除了为编译C++代码所需的大量定义。
更进一步,the scope of a symbol declared using #define
被限制在源文件是在。有效利用整个项目的象征需要使用它在所有的文件被重复#define
,使得它很难保持一致性。
随着亨克Holterman pointed out already,定义一个全局编译时符号的唯一维护的方式就是通过构建配置,因为这些符号在项目定义一次,适用于所有文件。
话虽如此,#define
可能是有用的验证条件编译按预期工作。如果在Visual Studio中将.cs文件的顶部设置为#define
,则活动代码将高亮显示,而非活动代码显示为灰色。您也可以使用它在单个文件中启用仅调试代码,例如在排查问题时。
因此,要回答你的问题,有没有好的用途,我知道在生产代码在C#中的#define语句,但它可以为测试一个方便的工具。
我可以给你一个警告,为什么不使用它。
如果你使用像ReSharper的是允许重命名,如果它们是不使用当前的配置,但一切都将编译块内也不会拿起变量等重命名的工具。
因此,如果您为具有在调试应用,然后检查它的一切都已经编制了条件一些代码做了重构,这并不意味着代码将在另一模式下进行编译,如释放。
它可能不是世界的末日,因为你的构建服务器将(应该)把它捡起来,但大家都知道,破坏构建意味着你欠啤酒队的休息!
我只过了它一个合法使用,那就是单元测试方法,其中有一个Conditional
属性:
public class Foo()
{
[Conditional("XYZ")]
public void Bar()
{
// Something cool...
}
}
我不得不添加#define
指令能够单元测试方法:
#define XYZ
public class FooTests
{
[Test]
public void BarShouldDoSomethingCool()
{
var subject = new Foo();
subject.Bar();
// assert something cool happened
}
}
没有#define
指令,该方法不会被称为单元测试,导致无论是不确定的或失败的测试。
'DEBUG'想起来 – 2012-04-02 07:18:11
看看[链接](http://msdn.microsoft.com/en-us/library/yt3yck0x%28v=vs.71%29.aspx) – 2012-04-02 07:18:18
它没用,它是就在那里踢球。 – Mehrdad 2012-04-02 07:24:11