是否总是执行局部变量赋值,即使变量未使用?

And*_*son 3 c# variable-assignment compiler-optimization

我有一个静态容器类,它包含一些类的句柄A:

public static class Container
{
    private static A _a;        
    public static void Register(A a) { _a = a; }
    public static void Run() { _a.DoIt(); }
}
Run Code Online (Sandbox Code Playgroud)

容器A实例的注册在A构造函数中执行:

public class A
{
    public A() { Container.Register(this); }        
    public void DoIt() { Console.WriteLine("Running!"); }
}
Run Code Online (Sandbox Code Playgroud)

现在,假设我A通过调用仅包含A实例化的方法来注册我的实例:

public void Init() { var a = new A(); }
Run Code Online (Sandbox Code Playgroud)

从理论上说,可以编译优化忽略这个任务,或者我可以100%肯定这A永远当我打电话实例化的Init方法?

示例当我运行以下代码时:

Init();
...
Container.Run();
Run Code Online (Sandbox Code Playgroud)

Container._a始终定义并将DoIt方法的输出写入控制台?

Mat*_*son 7

编译器通常不知道A的构造函数是否具有可观察的副作用,因此它总是会调用它.它可能不会保持变量'a'.

因此,将调用构造函数,但结果可能不会分配给变量; 相反,如果没有别的东西引用它,A对象可能只是立即注册垃圾收集.(在你的情况下,还有别的东西引用它 - 即Container类 - 所以它不会被垃圾收集!)

在您的情况下,构造函数显然在任何情况下都有副作用(因此编译器优化掉构造函数调用将是一个主要错误).

综上所述:

  • 始终会调用构造函数.
  • 可能无法将结果分配给局部变量,因为编译器知道它没有可观察到的副作用.
  • 在你的代码中,其他东西保留了对构造对象的引用,因此它不会被GCed.