如何C#编译器中删除Debug.Assert的公司在发布版本? [英] How does C# compiler remove Debug.Assert's in release builds?

查看:167
本文介绍了如何C#编译器中删除Debug.Assert的公司在发布版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我最近经历了一些代码,并考虑是否我需要小心放在 Debug.Assert的语句,如昂贵的操作或有副作用内的表达。但是,它出现的编译器可以非常聪明的完全删除断言语句和内心的表达。

I was recently going through some code and considering whether I need to be careful with the expressions placed inside Debug.Assert statements, such as expensive operations or those with side effects. However, it appears the compiler is pretty smart about completely removing the Assert statement and inner expressions.

例如,下面将只在调试打印建立:

For example, the following will only print on debug builds:

static void Main(string[] args)
{
    Debug.Assert(SideEffect());
}
private static bool SideEffect()
{
    Console.WriteLine("Side effect!");
    return true;
}

这会抱怨说 0 上发布的初始化建立之前正在使用:

And this will complain that o is being used before initialization on release builds:

static void Main(string[] args)
{
    object o;
    Debug.Assert(Initialize(out o));
    o.ToString();
}
private static bool Initialize(out object o)
{
    o = new object();
    return true;
}



它甚至似乎站起来,表情像这样的(打印后在这两种情况下):

It even seems to stand up to expressions such as this (printing "After" in both cases):

static void Main(string[] args)
{
    if (false) Debug.Assert(true);
    Console.WriteLine("After");
}



我是一个小的编译器是这里有多聪明惊讶和能力当 Debug.Assert的被删除正确检测的情况。因此,这让我好奇。

I was a little suprised with how smart the compiler is here and its ability to correctly detect cases when the Debug.Assert is removed. So, it got me curious..


  • 究竟是如何被声明删除?为了正确,如果正确地执行上面的语句删除语句之前的表达式树必须建立。

  • System.Diagnostics.Debug 类特殊的位置,或者是有可能建立类似处理你自己的方法?

  • 有什么方法来这里绝招预处理器?更妙的是,有没有一个可以在现实世界中的代码遇到的情况下,这可能是有问题的?

  • How exactly is the statement removed? The expression tree must be built before the statement is removed in order to properly execute the above if statement correctly.
  • Is the System.Diagnostics.Debug class special here, or is it possible to build your own methods with similar handling?
  • Are there any ways to "trick" the preprocessor here? Even better, are there situations that one might encounter in real-world code where this could be problematic?

推荐答案

Debug.Assert的声明了的 ConditionalAttribute ;作为文档状态,这种[我] ndicates来,除非指定的条件编译符号的定义是一个方法调用或属性应该被忽略的编译器。

Debug.Assert is declared with ConditionalAttribute; as the documentation states, this "[i]ndicates to compilers that a method call or attribute should be ignored unless a specified conditional compilation symbol is defined."

C#编译器有具体的支持该属性,并在发布版本中删除Debug.Assert的,所以这是从来没有内置表达式树的一部分。

The C# compiler has specific support for that attribute and removes the Debug.Assert during release builds, so it is never part of the built expression tree.

如果你的一个右击你的 Debug.Assert的语句,你应该能够去定义。 Visual Studio会告诉你代码从元数据生成的,在那里你可以看到应用了 [条件(DEBUG)] 属性。所以这个代码只尊重时 DEBUG 的#define 'D作为构建的一部分。

If you right-click on one of your Debug.Assert statements, you should be able to go to the definition. Visual Studio will show you "code" generated from the metadata, and there you can see the [Conditional("DEBUG")] attribute applied. So this code is only respected when DEBUG is #define'd as part of your build.

这篇关于如何C#编译器中删除Debug.Assert的公司在发布版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆