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

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

设想一个包含静态成员的generics类:

class Foo<T> { public static int member; } 

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

它可以很容易地被这样的代码validation:

 Foo<int>.member = 1; Foo<string>.member = 2; Console.WriteLine (Foo<int>.member); 

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

static字段在同一types的所有实例共享。 Foo<int>Foo<string>是两种不同的types。 这可以通过下面的代码行来certificate:

 // this prints "False" Console.WriteLine(typeof(Foo<int>) == typeof(Foo<string>)); 

至于在哪里有文档记载,可以在1.6.5节C#语言规范的字段 (对于C#3)中find以下内容:

一个静态字段确切地标识一个存储位置。 无论创build多less个实例,只有一个静态字段的副本。

如前所述; Foo<int>Foo<string>不是同一个类; 它们是由同一个generics类构造的两个不同的类。 上述文件的第4.4节概述了这种情况:

genericstypes声明本身表示一个未绑定的genericstypes,通过应用types参数,用作“蓝图”来形成许多不同的types。

这里的问题实际上是“通用类”根本不是类。

generics类定义只是类的模板,直到指定了它们的types参数,它们只是一段文本(或几个字节)。

在运行时,可以为模板指定一个types参数,从而使其生效,并创build一个现在完全指定types的类。 这就是为什么静态属性不是模板范围的,这就是为什么你不能在List<string>List<int>

这种关系反映了类与对象的关系。 就像类不存在直到你从它们实例化一个对象,generics类不存在,直到你根据模板创build一个类。

PS这是很有可能宣布

 class Foo<T> { public static T Member; } 

由此可见,静态成员不能共享,因为不同专业的T是不同的。

他们不共享。 不知道它在哪里被logging,但分析警告CA1000 ( 不要在genericstypes上声明静态成员 )因为使代码更复杂的风险而提出警告。

generics的C#实现更接近于C ++。 在这两种语言中, MyClass<Foo>MyClass<Bar>不共享静态成员,但在Java中它们是共享的。 在C#和C ++中, MyClass<Foo>在编译时内部创build全新的types,就像generics是一种macros一样。 您通常可以在堆栈跟踪中看到他们生成的名称,如MyClass'1MyClass'2 。 这就是为什么他们不共享静态variables。 在Java中,generics是通过使用非genericstypes的编译器生成代码更简单的方法来实现的,并添加了types转换。 因此, MyClass<Foo>MyClass<Bar>不会在Java中生成两个全新的类,而是它们都是同一个类MyClass ,这就是它们共享静态variables的原因。

他们并不真正分享。 因为该成员根本不属于该实例。 静态类成员属于类本身。 所以,如果你有MyClass.Number它对所有的MyClass.Number对象都是一样的,因为它甚至不依赖于对象。 您甚至可以调用或修改没有任何对象的MyClass.Number。

但是因为Foo <int>与Foo <string>不是同一个类,所以这两个数字是不共享的。

一个例子来显示这个:

 TestClass<string>.Number = 5; TestClass<int>.Number = 3; Console.WriteLine(TestClass<string>.Number); //prints 5 Console.WriteLine(TestClass<int>.Number); //prints 3 

国际海事组织,你需要testing它,但我认为

 Foo<int>.member = 1; Foo<string>.member = 2; Console.WriteLine (Foo<int>.member); 

将输出1因为我认为,在编译期间,编译器为您使用的每个generics类(例如: Foo<int>Foo<string> )创build一个类。

但我不是100%肯定=)。

备注:我认为使用这种静态属性并不是一个好的devise,也不是一个好习惯。