为什么不对用作泛型类型参数的类调用静态构造函数

本文关键字:调用 静态 构造函数 泛型类型参数 为什么不 | 更新日期: 2024-11-08 13:30:38

给定以下类:

public class Foo {
    static Foo() {
        Console.WriteLine("Foo is being constructed");
    }
}
public class Bar {
    public void ReferenceFooAsGenericTypeParameter<T>() {
        Console.WriteLine("Foo is being referenced as a generic type parameter");
    }
}
public class SampleClass
{
    public static void Main()
    {
        new Bar().ReferenceFooAsGenericTypeParameter<Foo>();
    }
}

输出为

Foo被引用为泛型类型参数

根据规范,这是有道理的:

在创建第一个实例或引用任何静态成员之前,将自动调用静态构造函数以初始化类。

但我很好奇为什么当类型作为泛型类型参数引用时不调用静态构造函数。

为什么不对用作泛型类型参数的类调用静态构造函数

为什么需要这样?

通常调用静态构造函数

的目的是确保在首次使用静态构造函数之前初始化静态构造函数中设置的任何状态。

仅使用 Foo 作为类型参数不会在其中使用任何状态,因此无需调用静态构造函数。

您可能想尝试创建一个具有副作用的静态变量初始值设定项(例如,然后打印到控制台的方法调用)并删除静态构造函数 - 在某些情况下,这可能会显着影响初始化的时间。它可能会在这里触发它。

这是因为您实际上无法仅通过作为泛型类型参数包含来以任何有意义的方式使用类型内容,该类型需要对其执行某些操作以保证调用静态构造函数。

您是对的,这符合规范。第 10.12 节(静态构造函数)指出:

静态构造函数的执行 由以下第一个事件触发,这些事件将发生在 应用领域:

· 将创建类类型的实例。

· 引用类类型的任何静态成员。

用作泛型类型参数都不是这些。

这里要注意的是,在创建 Bar 类型的对象new Bar().ReferenceFooAsGenericTypeParameter<Foo>();,您的 main 和 Bar 都没有创建 Foo 的实例,也没有访问它的任何成员,在呈现的情况下,类型本身只是作为参数传递。