在线编译器中的静态字段变量初始值设定项失败但在 VS 中有效

static field variable initializer FAILS in online compiler but works in VS

我想澄清一下 .NET 中静态字段初始值设定项的执行时间有多宽松。在在线编译器 (Fiddle) 中 运行 下面的代码时,我得到了 TypeInitializationException,但我在测试控制台应用程序中得到了预期的输出 1在 VS.

代码:

using System;
using SimpleInjector;   

public class Program
{
    public static IFactory Factory { get; set; }
        
    public interface IFactory { T GetInstance<T>() where T: class; }
    
    public class SimpleFactory: IFactory
    {
        private readonly Container _container;
        public SimpleFactory(Container container) { this._container = container; }
        public T GetInstance<T>() where T : class { return _container.GetInstance<T>(); }
    }
    
    public class Bar { public int Get() { return 1; } }

    public static class Foo
    {
        //static Foo() {}
        public static readonly int foo = Factory.GetInstance<Bar>().Get();
    }
        
    public static void Main()
    {
        var container = new Container();
        var factory = new SimpleFactory(container);
        
        container.RegisterInstance(Factory = factory);
        container.Register<Bar>();
                
        Console.WriteLine(Foo.foo);
    }
}

来自在线编译的堆栈跟踪:

[System.NullReferenceException: Object reference not set to an instance of an object.]
   at Program.Foo..cctor() :line 22

[System.TypeInitializationException: The type initializer for 'Foo' threw an exception.]
   at Program.Main() :line 33

什么给了?可以安全地假设在 visual studio 下构建时代码始终保证正常工作吗?谢谢你的时间。

根据C# language spec,这被特别指出为依赖于实现的东西:

If a static constructor exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.

您获得的唯一保证是,在首次使用静态字段之前必须一段时间

但是,正如您可能已经在 fiddle 中发现的那样,添加静态构造函数可以实现此目的。静态构造函数保证静态字段初始化器紧接在静态构造函数之前 运行 。好消息是静态构造函数的执行不依赖于实现(spec):

The execution of a static constructor is triggered by the first of the following events to occur within an application domain:

  • An instance of the class type is created.
  • Any of the static members of the class type are referenced.