2013-02-07 12 views
12

In C# ho una classe generica:È una variabile membro statica comune a tutte le istanze generiche C#?

public class MyGeneric<ParameterClass> where ParameterClass: MyGenericParameterClass, new() { 
    public static int Variable; 
} 

Ora in C++ se un'istanza di una classe template con parametri diversi ogni classe completa otterrebbe il proprio Variable, così I just can't say

MyGeneric.Variable = 1; // invalid in C++ 

in C++, ma sembra che posso farlo in C#.

vorrei chiarire ...

Se ho un generico con una variabile membro statica è che variabile condivisa tra tutte le istanze generici?

risposta

12

Section 25.1.4 of the ECMA C# Language specification

Una variabile statica in una dichiarazione di classe generica è condivisi tra tutte le istanze dello stesso tipo costruito chiuso (§26.5.2), ma è non condivisi tra le istanze di diverso chiuso costruite tipi. Queste regole si applicano indipendentemente dal fatto che il tipo di variabile statica contenga o meno qualsiasi parametro di tipo.

Si può vedere questo post del blog: Static fields in generic classes da Gus Perez

Non si può fare questo in C# pure.

MyGeneric.Variable = 1; 

Considerare il seguente esempio dalla specifica della lingua 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

No, non è condiviso.

Ogni classe MyGeneric<T> si risolverà in un diverso tipo di runtime, per ogni possibilità di T.

Verificare che non ci siano classi non MyGeneric non generiche con il membro statico Variable.

2

No, non lo è. I tipi generici possono essere "aperti" o "chiusi". Un tipo aperto è uno come List<T> in cui il parametro type non è definito; List<int> è un tipo chiuso.

In sostanza, il tipo aperto non viene considerato come un "Tipo" corretto dal runtime - solo le versioni chiuse sono tipi veri. Quindi, MyGeneric<int> e MyGeneric<string> sono due tipi completamente diversi e quindi hanno le proprie istanze della variabile statica.

Ciò è reso più evidente dal fatto che non è possibile chiamare il membro statico nel modo suggerito: MyGeneric.Variable non verrà compilato in C#.

Questa console codice dell'applicazione lo illustra molto semplicemente:

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 

Questi due sono le variabili statiche diverse trattati come classi separate.