通用静态字段初始化

时间:2011-09-16 00:30:20

标签: c# generics static

我对以下代码感到好奇:

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

正如我所知,当执行以下代码时,将初始化静态类Container:

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

我是对的吗?有关静态泛型类/成员初始化的任何解释都将受到赞赏。提前谢谢。

2 个答案:

答案 0 :(得分:8)

保证静态字段在您访问之前已初始化。 (而且,如果还有一个静态构造函数,那么在运行静态构造函数之前将初始化所有静态字段。)

对于泛型类,静态初始化基于每个类型工作,因此Container<int>的行为就好像它是Container<double>的完全不同的类。对于泛型类的所有静态部分实际上都是这样 - 每个类型都有自己的“副本”。

一个例子将更清楚地显示最后一点:

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

答案 1 :(得分:4)

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

public static class Container<T>
{
    public static readonly T[] EmptyArray;

    static Container()
    {
        EmptyArray = new T[];
    }
}

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

  

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

由于Container<string>Container<bool>不相同,因此对于每种类型的T,都会调用一次静态构造函数。