我有一些代码在Release版本和Debug版本之间表现不同。它在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();
}
为了排除故障,我简化了代码并以通用方式命名变量,方法returnEmptyList
和returnListWithOneItem
如下所示:
private List<string> returnEmptyList()
{
return new List<string>();
}
private List<string> returnListWithOneItem()
{
return new List<string> {"something"};
}
显然它永远不应该进入if
块,因为list2.Count
应该始终为1,但是当我在Release版本中执行它时,它 :
因此,显然有一些优化正在进行,因为您可以看到list1
无法访问,并且当单步执行时执行第416行然后立即跳转到第421行。我应该声明我的解决方案中的所有程序集都使用.NET Framework 4.6.2,我正在运行Visual Studio 2017版本15.3.5。
当我将构建更改为Debug并执行此操作时,它会执行第416,417行,并且在第418行显示list1.Count
为0且list2.Count
为1,并且它正确执行不输入if
块。
我正在尝试制作一个测试项目来重现这一点,但我不能。我正在寻找任何方法来深究这一点。我不仅仅想要一个让它消失的修复 - 我需要了解我做错了什么。
答案 0 :(得分:7)
好的,我很确定它是我的函数其余部分中的一个微妙错误的结果,它允许编译器优化if块并提前返回。我可以在这个测试项目中重现调试器的行为,在这种情况下它完全有意义:
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
{
}
当我使用调试器在Release版本中执行时,它似乎进入if
块,但实际上它只是完全优化了if
块并且调试器容易混淆地显示它执行行在if
块内,而不是跳过它:
编辑:我已经确认函数后面有一个错误导致了我的问题,调查器在查看发布版本代码时的行为只是让我感到困惑,由于编译器优化。
要清楚,我的问题是不正确的:该函数实际上在Release和Debug版本中都给出了相同的结果,但我错了。那是因为我遵循了这个(有缺陷的)序列:
if
块。if
块。 我认为(错误地)是我问题的根源。 这让我在上面看到了疯狂的追逐。很抱歉浪费你的时间,但我当然发现这项运动信息丰富。也许其他人将来会从我的错误中吸取教训。 :)