【发布时间】:2021-02-01 15:47:28
【问题描述】:
通常,当我制作控制台应用程序时,我会从以下内容开始:
using System;
namespace ColorOptProblemTest
{
class Program
{
const string HELP_TEXT = "";
static ConsoleColor Default = Console.ForegroundColor;
static void ShowHelp()
{
Console.ForegroundColor = ConsoleColor.Gray;
Console.WriteLine(HELP_TEXT);
Console.ForegroundColor = Default;
Environment.Exit(0);
}
static void ThrowError(string Message)
{
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("ERROR: " + Message);
ShowHelp();
}
static void ManageArgs(string[] args)
{
switch (args.Length)
{
case 0:
ThrowError("At least one argument is required.");
break;
}
}
static void Main(string[] args)
{
ManageArgs(args);
}
}
}
重要的是我把Console.ForegroundColor保存起来,等程序退出以后,让终端恢复到原来的颜色。
如果没有编译器优化,代码会按照应有的方式执行所有操作,并且会像魅力一样工作。经过优化,程序退出时,终端颜色为红色。
这可能是优化器中的某种错误吗?也许我只是缺少一些基本的东西。
【问题讨论】:
-
我看不到您保存和加载前景色的位置。您所说的这种“优化”是什么?你是说 RELEASE 还是 DEBUG?
-
@Steve 在 Release 属性设置中,您可以设置是否要优化。保存是在我将默认设置为 Console.ForegroundColor 的类开始时完成的。加载在退出之前完成。这一切都可以在没有优化的情况下工作,但由于某种原因,经过优化就不行了。
-
您依赖于不确定的行为来初始化静态字段。见重复。如果您想在更改之前使用该字段保存值,则需要使用确定性机制进行初始化。
-
@PeterDuniho 谢谢。就这样我理解正确:由于优化,静态字段将在使用它们之前的某个时间进行初始化。这就是为什么在没有优化的情况下,程序可以正常工作的原因。如果我理解正确,可以通过向类添加一个空的构造函数来避免这种情况。那么在调用第一个方法后,字段会被初始化吗?还是我需要显式调用构造函数?据我所知,这种延迟初始化是出于性能原因而完成的,因此变量仅在需要时才被初始化,对吗?
-
是的,一个空的 static 构造函数会在访问任何静态成员(包括静态方法)之前执行,并且当静态构造函数存在时,静态字段初始化确定性完成在执行静态构造函数之前。您不需要(也不能)显式调用静态构造函数。
标签: c# .net compiler-optimization