gpt4 book ai didi

c# - C# 编译器如何删除发布版本中的 Debug.Assert?

转载 作者:IT王子 更新时间:2023-10-29 04:24:32 26 4
gpt4 key购买 nike

我最近检查了一些代码并考虑是否需要小心放置在 Debug.Assert 语句中的表达式,例如昂贵的操作或具有副作用的操作。但是,编译器似乎非常聪明地完全删除了 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;
}

它甚至似乎经得起这样的表达(在两种情况下都打印“After”):

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

我对编译器的智能程度及其在删除 Debug.Assert 时正确检测案例的能力感到有点惊讶。所以,这让我很好奇..

  • 该声明究竟是如何删除的?为了正确执行上述if语句,必须在删除语句之前构建表达式树。
  • 这里的 System.Diagnostics.Debug 类是特殊的,还是可以构建您自己的具有类似处理的方法?
  • 这里有什么方法可以“欺骗”预处理器吗?更好的是,在现实世界的代码中是否存在可能会出现问题的情况?

最佳答案

Debug.Assert 声明为 ConditionalAttribute ;正如文档所述,这“[i] 向编译器表明,除非定义了指定的条件编译符号,否则应忽略方法调用或属性。”

C# 编译器对该属性有特定的支持,并在发布构建期间删除了 Debug.Assert,因此它永远不会成为构建表达式树的一部分。

如果您右键单击其中一个 Debug.Assert 语句,您应该能够转到定义。 Visual Studio 将向您显示从元数据生成的“代码”,您可以在其中看到应用的 [Conditional("DEBUG")] 属性。因此,仅当 DEBUG 作为构建的一部分被 #define 时,才会遵守此代码。

关于c# - C# 编译器如何删除发布版本中的 Debug.Assert?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5750482/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com