泛型类的静态成员是否与特定实例绑定?

maf*_*afu 76 .net c# generics static

这更像是一个文档,而不是一个真实的问题.这似乎还没有在SO上得到解决(除非我错过了),所以这里有:

想象一下包含静态成员的泛型类:

class Foo<T> {
    public static int member;
}
Run Code Online (Sandbox Code Playgroud)

是否有每个特定类的成员的新实例,或者所有Foo类类只有一个实例?

可以通过以下代码轻松验证:

Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);
Run Code Online (Sandbox Code Playgroud)

结果是什么,这种行为记录在哪里?

Fre*_*örk 86

static跨所有相同类型的实例共享一个字段.Foo<int>并且Foo<string>是两种不同的类型.这可以通过以下代码行证明:

// this prints "False"
Console.WriteLine(typeof(Foo<int>) == typeof(Foo<string>));
Run Code Online (Sandbox Code Playgroud)

至于记录的位置,可以在1.6.5 C#语言规范的字段(C#3)中找到以下内容:

静态字段确切地标识一个存储位置.无论创建了多少个类实例,都只有一个静态字段的副本.

如前所述; Foo<int>并且Foo<string>不是同一个班级; 它们是由同一个泛型类构造的两个不同的类.如何发生这种情况在上述文件的第4.4节中概述:

泛型类型声明本身表示一种未绑定的泛型类型,它通过应用类型参数用作形成许多不同类型的"蓝图".

  • 如果你用C#和Java开发,这就是问题所在.虽然`Foo <int>`和`Foo <String>`是C#中的不同类型,但它们在Java中是相同的**类型,因为Java处理泛型(类型擦除/编译器技巧). (24认同)

SWe*_*eko 16

这里的问题实际上是"泛型类"根本不是类.

通用类定义只是类的模板,在指定类型参数之前,它们只是一段文本(或少数几个字节).

在运行时,可以为模板指定一个类型参数,从而使其生效,并创建一个现在完全指定类型的类.这就是静态属性不是模板范围的原因,这就是为什么你不能在List<string>和之间强制转换的原因List<int>.

这种关系有点反映了阶级 - 客体关系.就像类不存在一样*直到你从它们实例化一个对象,在你根据模板创建一个类之前,泛型类就不存在了.

PS很有可能宣布

class Foo<T> {
    public static T Member;
}
Run Code Online (Sandbox Code Playgroud)

从中可以明显看出静态成员无法共享,因为不同的专业化对T是不同的.