C#泛型静态构造函数

56

对于传入泛型参数的每种类型,像这样在泛型类上使用静态构造函数会运行吗:

 class SomeGenericClass<T>
 {
      static List<T> _someList;
      static SomeGenericClass()
      {
          _someList = new List<T>();
      }
 }

使用这种方法是否有任何缺点?

4个回答

68
是的,静态构造函数将为每个封闭的类类型(在指定类型参数时创建的类型)调用一次。请参见 C# 3 specification 第10.12节中的说明。
引用如下: 封闭类类型的静态构造函数在给定应用程序域中最多执行一次。
另外还有以下内容:
由于静态构造函数对于每个封闭构造的类类型仅执行一次,因此它是一个方便的地方,用于强制运行时检查类型参数,这些检查无法通过约束(§10.1.5)在编译时检查。例如,以下类型使用静态构造函数来强制要求类型参数为枚举类型:
class Gen<T> where T: struct
{
    static Gen() {
        if (!typeof(T).IsEnum) {
            throw new ArgumentException("T must be an enum");
        }
    }
}

这也与阅读§4.4.2 开放类型和封闭类型相关:
在运行时,泛型类型声明中的所有代码都在一个封闭的构造类型上下文中执行,该构造类型是通过将类型参数应用于泛型声明而创建的。泛型类型中的每个类型参数都绑定到特定的运行时类型。所有语句和表达式的运行时处理始终发生在封闭类型中,而开放类型仅在编译时处理期间发生。
每个封闭构造类型都有自己的一组静态变量,与任何其他封闭构造类型都不共享。
您可以运行此程序,它证明了静态构造函数被调用了三次,而不仅仅是一次:
public class Program
{
    class SomeGenericClass<T>
    {
        static SomeGenericClass()
        {
            Console.WriteLine(typeof(T));
        }
    }

    class Baz { }

    static void Main(string[] args)
    {
        SomeGenericClass<int> foo = new SomeGenericClass<int>();
        SomeGenericClass<string> bar = new SomeGenericClass<string>();
        SomeGenericClass<Baz> baz = new SomeGenericClass<Baz>();
    }
}

输出:

System.Int32
System.String
Program+Baz

6
@Jouke van der Maas提到了一个静态类吗?问题是关于一个泛型类的静态构造函数,而不是一个静态类...请问需要翻译其他内容吗? - Thomas Levesque
这不是其中任何一个,所以它仍然适用 :) - Jouke van der Maas

2

它可以工作,但每次使用时都会创建一个新的“实例”。


0

是的,泛型类型的静态成员和构造函数是针对泛型参数特定的,并且将为每个不同的类型运行。没有真正的缺点。只需在将非泛型类重构为泛型类时小心。


0

是的,它将为您提供的每种类型运行,因为对于每个不同的提供类型,您都会获得单独的类型。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接