【问题标题】:Generic static fields initialization通用静态字段初始化
【发布时间】:2011-09-16 00:30:19
【问题描述】:

我只是对以下代码感到好奇:

public static class Container<T>
{
    public static readonly T[] EmptyArray = new T[0];
}

据我了解,静态类 Container 将在以下代码执行时被初始化:

...
var emptyArray = Container<int>.EmptyArray;
...

我说的对吗?任何关于静态泛型类/成员初始化的解释都将不胜感激。提前致谢。

【问题讨论】:

    标签: c# generics static


    【解决方案1】:

    保证是在您访问静态字段之前对其进行初始化。 (另外,如果还有一个静态构造函数,那么所有的静态字段都会在静态构造函数运行之前被初始化。)

    对于泛型类,静态初始化基于每个类型进行,因此Container&lt;int&gt; 的行为与Container&lt;double&gt; 完全不同。这实际上适用于泛型类的所有静态部分——每种类型都有自己的“副本”。

    一个例子将更清楚地说明最后一点:

    static class Foo<T>
    {
        static int count = 0;
        public static int Increment()
        {
            return ++count;
        }
    }
    
    public class Program
    {
        public static void Main()
        {
            Console.WriteLine(Foo<int>.Increment());
            Console.WriteLine(Foo<int>.Increment());
            Console.WriteLine(Foo<double>.Increment());
        }
    }
    

    输出:

    1
    2
    1
    

    【讨论】:

    • 哦,所以答案是“是”:)
    【解决方案2】:

    静态字段初始值设定项实际上已移至类的静态构造函数(类型初始值设定项)中。所以你的代码会自动编译成这个:

    public static class Container<T>
    {
        public static readonly T[] EmptyArray;
    
        static Container()
        {
            EmptyArray = new T[];
        }
    }
    

    来自MSDN 关于静态构造函数:

    在创建第一个实例或引用任何静态成员之前自动调用它[静态构造函数]。

    由于Container&lt;string&gt;Container&lt;bool&gt; 不一样,所以对于T 的每种类型都调用一次静态构造函数。

    【讨论】:

    • 我误解了静态构造函数的想法——我认为静态构造函数是在程序的一开始就被调用的,所以这个代码示例对我来说似乎很奇怪。谢谢。
    • @danyloid:运行时允许在使用类成员之前的任何时间调用静态构造函数。这可能在程序开始时,或者就在您第一次实际使用它之前。
    猜你喜欢
    • 1970-01-01
    • 2014-10-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-15
    • 2012-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多