我最近正在浏览一些代码,并考虑是否需要注意Debug.Assert
语句中的表达式,例如昂贵的操作或带有副作用的表达式。但是,看起来编译器对于完全删除Assert
语句和内部表达式非常聪明。C#编译器如何在发布版本中删除Debug.Assert?
例如,下面将只在调试打印构建:
static void Main(string[] args)
{
Debug.Assert(SideEffect());
}
private static bool SideEffect()
{
Console.WriteLine("Side effect!");
return true;
}
这会抱怨正在使用o
之前发布的初始化建立:
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;
}
它甚至似乎停滞不前直到这样的表达式(在两种情况下打印“之后”):
static void Main(string[] args)
{
if (false) Debug.Assert(true);
Console.WriteLine("After");
}
我对编译器在这里的智能以及在Debug.Assert
被删除时正确检测病例的能力感到有点惊讶。所以,它让我好奇......
- 该语句到底是如何删除的?表达式树必须在删除语句之前构建,以正确执行上述
if
语句。 - 这里的
System.Diagnostics.Debug
类是特别的,还是可以用类似的处理来构建你自己的方法? - 有什么方法可以在这里“欺骗”预处理器吗?更好的是,在真实世界的代码中可能会遇到哪些情况可能会遇到问题?
请参阅http://blogs.msdn.com/b/ericlippert/archive/2009/09/10/what-s-the-difference-between-conditional-compilation-and-the-conditional-attribute.aspx关于这个问题的一些想法。 – 2011-04-22 05:13:27