gpt4 book ai didi

c# - 为什么这个程序在 Release build 中进入 if block ,而在 Debug build 中不进入?

转载 作者:太空狗 更新时间:2023-10-29 17:51:32 24 4
gpt4 key购买 nike

我有一些代码在发布版本和调试版本之间表现不同。它在 Debug 中表现正确,但在 Release 中表现不正确。

我有一个返回 ReadOnlyCollection<MyCustomClass> 的函数.其中一节是这样的:

        var result = new List<MyCustomClass>();
...
var list1 = this.returnEmptyList();
var list2 = this.returnListWithOneItem();
if (list1.Count == 0 && list2.Count == 0)
{
functionOutVariable = string.Empty;
return result.AsReadOnly();
}

为了排除故障,我简化了代码并以通用方式命名了变量,以及方法 returnEmptyListreturnListWithOneItem显示在这里:

    private List<string> returnEmptyList()
{
return new List<string>();
}

private List<string> returnListWithOneItem()
{
return new List<string> {"something"};
}

显然它永远不应该输入 if阻止因为 list2.Count应该始终为 1,但是当我在发布版本中执行它时,它:

enter image description here

所以显然有一些优化正在进行,因为您可以看到 list1无法访问,单步执行时执行第 416 行,然后立即跳转到第 421 行。我应该声明我的解决方案中的所有程序集都使用 .NET Framework 4.6.2,并且我正在运行 Visual Studio 2017 版本 15.3.5。

当我将构建更改为调试并执行它时,它会执行第 416、417 行,并在第 418 行显示 list1.Count是 0 和 list2.Count是 1,并且它正确地输入 if block 。

我正在尝试制作一个测试项目来重现这一点,但我做不到。我正在寻找任何方法来解决这个问题。我不只是想要一个让它消失的修复程序 - 我需要了解我做错了什么。

最佳答案

好吧,我很确定这是我函数其余部分中的一个细微错误的结果,该错误允许编译器只优化 if block 并提前返回。我可以在这个测试项目中重现调试器的行为,在这种情况下它完全有意义:

class Program
{
static void Main(string[] args)
{
var test = new MyClass();
test.DoTest(out var result);
Console.WriteLine(result);
Console.ReadKey();
}
}

class MyClass
{
public ReadOnlyCollection<MyCustomClass> DoTest(out string functionOutVariable)
{
var result = new List<MyCustomClass>();
var list1 = this.returnEmptyList();
var list2 = this.returnListWithOneItem();
if (list1.Count == 0 && list2.Count == 0)
{
functionOutVariable = string.Empty;
return result.AsReadOnly();
}
functionOutVariable = string.Empty;
return result.AsReadOnly();
}

private List<string> returnEmptyList()
{
return new List<string>();
}

private List<string> returnListWithOneItem()
{
return new List<string> { "something" };
}
}

class MyCustomClass
{

}

当我使用调试器在发布版本中执行时,它似乎进入了 if block ,但实际上它只是完全优化了 if block 和调试器令人困惑地显示它执行 if block 内的行而不是跳过它:

enter image description here

编辑:我已经确认函数后面有一个错误导致了我的问题,调试器在查看发布构建代码时的行为只是让我感到困惑,因为编译器优化。

需要说明的是,我的问题是不正确的:该函数实际上在 Release 和 Debug 版本中给出了相同的结果,但我错了。那是因为我遵循了这个(有缺陷的)序列:

  1. 我有一个失败的测试(针对发布版本)。
  2. 我使用调试器(仍在发布版本中)运行测试并看到它显然错误地进入了 if block 。
  3. 然后我将构建切换到调试并使用调试器运行测试并看到它跨过了 if block 。 我(错误地)认为这是我的问题的根源。

这让我开始了上面看到的野鹅追逐。很抱歉浪费你的时间,但我确实发现这个练习很有用。也许将来会有其他人从我的错误中吸取教训。 :)

关于c# - 为什么这个程序在 Release build 中进入 if block ,而在 Debug build 中不进入?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46850269/

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