简体   繁体   English

C#Generic Static Constructor

[英]C# Generic Static Constructor

Will a static constructor on a generic class be run for every type you pass into the generic parameter such as this: 是否会为传递给泛型参数的每个类型运行泛型类上的静态构造函数,例如:

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

Are there any draw backs to using this approach? 使用这种方法是否有任何缺点?

Yes, the static constructor will be called once for each closed class type (the type created when you specify the type parameters). 是的,对于每个封闭的类类型(指定类型参数时创建的类型),将为静态构造函数调用一次。 See the C# 3 specification , §10.12 Static constructors. 请参阅C#3规范 ,§10.12静态构造函数。

The static constructor for a closed class type executes at most once in a given application domain. 封闭类类型的静态构造函数在给定的应用程序域中最多执行一次。

and also: 并且:

Because the static constructor is executed exactly once for each closed constructed class type, it is a convenient place to enforce run-time checks on the type parameter that cannot be checked at compile-time via constraints (§10.1.5). 因为静态构造函数对于每个关闭的构造类类型只执行一次,所以对于无法在编译时通过约束(第10.1.5节)检查的类型参数强制执行运行时检查是一个方便的地方。 For example, the following type uses a static constructor to enforce that the type argument is an enum: 例如,以下类型使用静态构造函数来强制类型参数是枚举:

class Gen<T> where T: struct
{
    static Gen() {
        if (!typeof(T).IsEnum) {
            throw new ArgumentException("T must be an enum");
        }
    }
}

It is also relevant to read §4.4.2 Open and closed types: 阅读§4.4.2开放和封闭类型也是相关的:

At run-time, all of the code within a generic type declaration is executed in the context of a closed constructed type that was created by applying type arguments to the generic declaration. 在运行时,泛型类型声明中的所有代码都是在通过将类型参数应用于泛型声明而创建的闭合构造类型的上下文中执行的。 Each type parameter within the generic type is bound to a particular run-time type. 泛型类型中的每个类型参数都绑定到特定的运行时类型。 The run-time processing of all statements and expressions always occurs with closed types, and open types occur only during compile-time processing. 所有语句和表达式的运行时处理始终以闭合类型进行,而打开类型仅在编译时处理期间发生。

Each closed constructed type has its own set of static variables, which are not shared with any other closed constructed types. 每个闭合构造类型都有自己的一组静态变量,这些变量不与任何其他闭合构造类型共享。

This program that you can run yourself demonstrates that the static constructor is called three times, not just once: 您可以自己运行的这个程序演示了静态构造函数被调用三次,而不只是一次:

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>();
    }
}

Output: 输出:

System.Int32
System.String
Program+Baz

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

Yes, static members and constructors for generic types are specific to a generic parameter and will be run for every different type. 是的,泛型类型的静态成员和构造函数特定于泛型参数,并将针对每种不同类型运行。 There are no real drawbacks. 没有真正的缺点。 Just be careful when refactoring a non-generic class into a generic one. 将非泛型类重构为泛型类时要小心。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM