这更像是一个文档,而不是一个真实的问题。这似乎还没有在SO上解决(除非我错过了),所以这里是:
想象一个包含静态成员的泛型类:
class Foo<T> {
public static int member;
}
是否每个特定类都有一个新成员实例,或者所有Foo类都只有一个实例?
可以通过以下代码轻松验证:
Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);
结果是什么,这种行为记录在哪里?
答案 0 :(得分:85)
static
字段在所有相同类型的实例中共享。 Foo<int>
和Foo<string>
是两种不同的类型。这可以通过以下代码行证明:
// this prints "False"
Console.WriteLine(typeof(Foo<int>) == typeof(Foo<string>));
至于记录的位置,可以在C#语言规范的 1.6.5字段部分(C#3)中找到以下内容:
静态字段只标识一个 存储位置。无论多少 创建一个类的实例, 只有一份副本 静态场。
如前所述; Foo<int>
和Foo<string>
不是同一个类;它们是由同一个泛型类构造的两个不同的类。如何发生这种情况概述于上述文件的第4.4节:
泛型类型声明本身, 表示未绑定的泛型类型 被用作形成许多人的“蓝图” 不同的类型,通过申请 类型参数。
答案 1 :(得分:14)
这里的问题实际上是“泛型类”根本不是类。
通用类定义只是类的模板,在指定类型参数之前,它们只是一段文本(或少数几个字节)。
在运行时,可以为模板指定一个类型参数,从而使其生效,并创建一个现在完全指定类型的类。这就是静态属性不是模板范围的原因,这就是为什么你不能在List<string>
和List<int>
之间进行投射。
这种关系有点反映了阶级 - 对象的关系。就像类不存在一样*直到你从它们实例化一个对象,在你根据模板创建一个类之前,泛型类不存在。
P.S。很有可能宣布
class Foo<T> {
public static T Member;
}
从这一点可以明显看出,静态成员无法共享,因为不同的专业化不同。
答案 2 :(得分:4)
他们没有分享。不知道它在哪里记录但是分析警告CA1000(不要在泛型类型上声明静态成员)因为存在使代码更复杂的风险而发出警告。
答案 3 :(得分:1)
他们并没有真正分享。 因为该成员根本不属于该实例。 静态类成员属于类本身。 因此,如果你有MyClass.Number,它对所有MyClass.Number对象都是相同的,因为它甚至不依赖于对象。 您甚至可以在没有任何对象的情况下调用或修改MyClass.Number。
但是自从Foo&lt; int&gt;与Foo&lt;字符串&gt;这两个数字不共享。
举例说明:
TestClass<string>.Number = 5;
TestClass<int>.Number = 3;
Console.WriteLine(TestClass<string>.Number); //prints 5
Console.WriteLine(TestClass<int>.Number); //prints 3
答案 4 :(得分:-3)
IMO,你需要测试它,但我认为
Foo<int>.member = 1;
Foo<string>.member = 2;
Console.WriteLine (Foo<int>.member);
将输出1
,因为我认为在编译期间,编译器会为您使用的每个泛型类创建1个类(在您的示例中为Foo<int>
和Foo<string>
)。
但我不是100%肯定=)。
备注:我认为使用这种静态属性不是一个好的设计也不是一个好的做法。