C#Generic Static Constructor

时间:2010-05-29 20:56:27

标签: c# generics

对于传递给泛型参数的每个类型,是否会为泛型类运行静态构造函数,如下所示:

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

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

4 个答案:

答案 0 :(得分:61)

是的,对于每个封闭的类类型(指定类型参数时创建的类型),将为静态构造函数调用一次。请参阅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

答案 1 :(得分:2)

它会起作用,但会为您使用的每种类型创建一个新的“实例”。

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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