2013-02-07 69 views
12

在C#中我有一个泛型类:是所有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#中这样做。

我想澄清......

如果我有一个通用的与静态成员变量是变量的所有属实例之间共享?

回答

12

Section 25.1.4 of the ECMA C# Language specification

在通用类声明的静态变量之间 共享相同的封闭构造类型(§26.5.2)的所有实例,但是不 之间构成不同的闭合的实例共享类型。 无论静态变量 的类型是否涉及任何类型参数,都适用这些规则。

您可能会看到这个博客帖子:Static fields in generic classes通过Gus 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<T>类都将解析为不同的运行时类型,每种可能性为T

请检查是否没有非通用的MyGeneric类与Variable静态成员。

2

不,它不是。泛型类型可以是“打开”或“关闭”。开放类型与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; 
} 
6
MyGeneric<MyClass>.Variable 
MyGeneric<MyOther>.Variable 

这两个都像独立的类来看待不同的静态变量。