0

在看了这么多与此相关的复杂问题之后,我想询问以下具有静态字段初始化的代码的解释。我想知道的另一件事是静态字段初始化的要求。在什么情况下会有帮助??

using System;

class Test
{
    static void Main()
    {
        Console.WriteLine("{0} {1}", B.Y, A.X);
    }

    public static int F(string s)
    {
        Console.WriteLine(s);
        return 1;
    }
}

class A
{
    static A()
    { }

    public static int X = Test.F("Init A");
}

class B
{
    static B()
    { }

    public static int Y = Test.F("Init B");
}

输出:

初始化 B

初始化 A

1 1

当不存在静态构造函数时,输出可能会有所不同。我无法理解其背后的原理。静态字段初始化给这个片段带来了什么不同?有人可以帮忙吗。我是 c# 的新手。

4

1 回答 1

4

当一个类型具有静态构造函数时,运行时被限制为在第一次使用该类型的任何成员之前立即执行所有类型初始化。

当它没有静态构造函数时,运行时有更多的自由 - 它必须在第一次使用静态字段之前或构造实例之前的某个时间点执行类型初始化程序,但仅此而已。您甚至可以观察到在没有执行类型初始化程序的情况下不会触及正在执行的静态字段的静态方法。

在您的情况下,两者都有静态构造函数,A并且B访问成员的顺序是 B 首先是 A,因此是您的输出。如果没有这些静态构造函数,您仍然可以保证得到“1 1”作为最后一行,并且仍然会得到“Init A”和“Init B”,但不能保证它们的顺序。

这只是指定语言和运行时的方式 - 通常它没有影响,因为通常类型初始化器应该只是设置类型,没有其他副作用。理想情况下,类型初始化器应该尽可能少地做——如果它们由于某种原因失败,则该类型将永远无法使用;类型初始化器不会重试。

有关更多详细信息,请参阅我的beforefieldinit文章.NET 4.0 类型初始化程序更改博客文章。

于 2014-12-09T10:00:04.357 回答