【问题标题】:C# Generic Static ConstructorC# 通用静态构造函数
【发布时间】:2010-05-29 20:56:26
【问题描述】:

是否会为您传递给泛型参数的每种类型运行泛型类上的静态构造函数,例如:

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

使用这种方法有什么缺点吗?

【问题讨论】:

    标签: c# generics


    【解决方案1】:

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

    在运行时,泛型类型声明中的所有代码都在封闭构造类型的上下文中执行,该封闭构造类型是通过将类型参数应用于泛型声明而创建的。泛型类型中的每个类型参数都绑定到特定的运行时类型。所有语句和表达式的运行时处理总是发生在封闭类型中,而开放类型只发生在编译时处理期间。

    每个封闭构造类型都有自己的一组静态变量,不与任何其他封闭构造类型共享。

    这个您可以自己运行的程序演示了静态构造函数被调用了 3 次,而不仅仅是一次:

    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 系统字符串 程序+巴兹

    【讨论】:

    • @Jouke van der Maas,谁谈到了静态类?问题是关于泛型类的静态构造函数,而不是静态类...
    • 两者都不是,所以它仍然适用:)
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

        【解决方案4】:

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

        【讨论】:

          猜你喜欢
          • 2011-10-07
          • 2011-04-19
          • 2011-05-06
          • 2014-03-14
          • 2014-07-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-03-01
          相关资源
          最近更新 更多