2012-04-02 42 views
2

我知道C#中的#define可以让你定义一个符号作为传递给#if指令的表达式,并且表达式将计算为true在C#中使用#define的真实世界示例?

但我想不出此功能的任何实际使用中,做任何人都知道它真正的用途?

+7

'DEBUG'想起来 – 2012-04-02 07:18:11

+0

看看[链接](http://msdn.microsoft.com/en-us/library/yt3yck0x%28v=vs.71%29.aspx) – 2012-04-02 07:18:18

+3

它没用,它是就在那里踢球。 – Mehrdad 2012-04-02 07:24:11

回答

6

目前根本没有一个整体很多关于它的用途。

随着#define可以定义常量条件编译,你通常会从构建配置控制这些。

1

#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,每个都有自己的一套定义的符号,可以进行检查,并应用到整个解决方案或单个项目不接触的源文件。

+2

这个答案不显示'#define'的使用 – 2012-04-02 07:37:17

+2

@AndrewCooper我已经更新了我的答案。 – Steve 2012-04-02 11:49:27

+0

-1 OP是要求一个真实世界的例子。 – MattDavey 2012-08-03 15:25:23

2
#if DEBUG 
    var jwriter = new VerboseJsonWriter(0); 
#else 
    var jwriter = new TerseJsonWriter(); 
#endif 

第一个以一种漂亮的方式格式化JSON,包括缩进,新行上的所有内容等,以便调试时人类可读。

因此,在生产带宽优化使用和东西快速加载

第二个放置在一个样样在行,没有任何空白。

+3

这个答案没有显示使用的'#define' – 2012-04-02 07:37:36

+0

@AndrewCooper--正如Henk Holterman的回答中已经提到的那样,这些通常是从构建过程中传递过来的。但是这仍然证明了这种符号的用途。 – 2012-04-02 07:50:09

+1

是的,但OP没有询问符号的使用,他问我们是否会使用'#define'指令。 – 2012-04-02 12:23:10

1

你可以在你的代码调试记录器,你不想在你的发布代码使用,因此你应该使用#define

#if DEBUG_LOG 
DebuggingTool.Activate(); 
#else 
DebuggingTool.Deactivate(); 
#endif 

而在VS 2010中,你可以生成选项卡上conditional compilation symbols添加添加全局符号

+2

没有'#define'在这里使用或需要。 – 2012-04-02 07:41:51

+1

我添加的代码下面一行说,你应该从项目属性的生成选项卡中添加符号:条件编译符号 – ionden 2012-04-02 07:44:24

+0

-1这是#一个例子,如果/#别人 - 的问题问的#define的现实世界的例子 – MattDavey 2012-08-03 15:26:08

4

编译时符号的最常见用法是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语句,但它可以为测试一个方便的工具。

1

我可以给你一个警告,为什么不使用它。

如果你使用像ReSharper的是允许重命名,如果它们是不使用当前的配置,但一切都将编译块内也不会拿起变量等重命名的工具。

因此,如果您为具有在调试应用,然后检查它的一切都已经编制了条件一些代码做了重构,这并不意味着代码将在另一模式下进行编译,如释放。

它可能不是世界的末日,因为你的构建服务器将(应该)把它捡起来,但大家都知道,破坏构建意味着你欠啤酒队的休息!

1

我只过了它一个合法使用,那就是单元测试方法,其中有一个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指令,该方法不会被称为单元测试,导致无论是不确定的或失败的测试。