所有 C# 泛型实例的静态成员变量是不是通用?
Posted
技术标签:
【中文标题】所有 C# 泛型实例的静态成员变量是不是通用?【英文标题】:Is a static member variable common for all C# generic instantiations?所有 C# 泛型实例的静态成员变量是否通用? 【发布时间】:2013-01-22 19:15:10 【问题描述】:在 C# 中,我有一个泛型类:
public class MyGeneric<ParameterClass> where ParameterClass: MyGenericParameterClass, new()
public static int Variable;
现在在 C++ 中,如果我用不同的参数实例化一个模板类,每个完整的类都会得到它自己的 Variable
,所以 I just can't say
MyGeneric.Variable = 1; // invalid in C++
在 C++ 中,但似乎我可以在 C# 中这样做。
我想澄清一下...
如果我有一个带有静态成员变量的泛型,该变量是否在所有泛型实例之间共享?
【问题讨论】:
【参考方案1】:Section 25.1.4 of the ECMA C# Language specification
泛型类声明中的静态变量在它们之间共享 相同封闭构造类型的所有实例(第 26.5.2 节),但 不同封闭构造类型的实例之间不共享。 这些规则适用于无论静态类型是否 变量是否涉及任何类型参数。
您可能会看到这篇博文:Static fields in generic classesGus Perez
你也不能在 C# 中做到这一点。
MyGeneric.Variable = 1;
考虑以下来自 ECMA 语言规范的示例。
class C<V>
static int count = 0;
public C()
count++;
public static int Count
get return count;
class Application
static void Main()
C<int> x1 = new C<int>();
Console.WriteLine(C<int>.Count); // Prints 1
C<double> x2 = new C<double>();
Console.WriteLine(C<double>.Count); // Prints 1
Console.WriteLine(C<int>.Count); // Prints 1
C<int> x3 = new C<int>();
Console.WriteLine(C<int>.Count); // Prints 2
【讨论】:
【参考方案2】:MyGeneric<MyClass>.Variable
MyGeneric<MyOther>.Variable
这两个是不同的静态变量,被视为单独的类。
【讨论】:
【参考方案3】:不,不是。泛型类型可以是“开放的”或“封闭的”。开放类型类似于List<T>
,其中未定义类型参数; List<int>
是封闭类型。
本质上,运行时不会将开放类型视为正确的“类型” - 只有封闭版本才是真正的类型。所以,MyGeneric<int>
和 MyGeneric<string>
是两种完全不同的类型,因此有它们自己的静态变量实例。
您不能以您建议的方式调用静态成员这一事实使这一点变得更加明显:MyGeneric.Variable
不会在 C# 中编译。
这个控制台应用程序代码非常简单地说明了这一点:
class Program
static void Main(string[] args)
Test<int>.i = 2;
Test<string>.i = 8;
Console.WriteLine(Test<int>.i); // would write "8" if the fields were shared
Console.WriteLine(Test<string>.i);
// Console.WriteLine(Test.i); // does not compile
// Console.WriteLine(Test<>.i); // does not compile
class Test<T>
public static int i;
【讨论】:
【参考方案4】:不,不共享。
对于T
的每种可能性,每个MyGeneric<T>
类都将解析为不同的运行时类型。
请检查不存在具有Variable
静态成员的非泛型MyGeneric
类。
【讨论】:
【参考方案5】:如上所述,您的问题的答案是否定的。但是,您可以做的是使用泛型类的父类,并在其中放置静态变量。您需要调用的任何方法都可以抽象到该父类中。
abstract class MyBase
protected static MyBase selected;
public abstract void Deselect();
class MyGeneric<T> : MyBase
public void Select()
if (selected != null)
if (selected != this)
selected.Deselect();
selected = this;
//...
public override void Deselect()
//...
【讨论】:
以上是关于所有 C# 泛型实例的静态成员变量是不是通用?的主要内容,如果未能解决你的问题,请参考以下文章