I need a certain class to contain a static member that keeps track of everytime an instance of that class is instantiated, essentially so that each instance of the class has a unique index. It works with a non-generic class but this generic implementation fails whenever the type T differs between instances:
class A<T> { private static int counter; private static int Counter { get { Increment(); return counter; } } private static void Increment() { counter++; } public int Index; public A() { this.Index = Counter; // using A<T>.Counter makes no difference Console.WriteLine(this.Index); } } class Program { static void Main(string[] args) { var a = new A<string>(); var b = new A<string>(); var c = new A<string>(); var d = new A<int>(); } }
The output is:
1
2
3
1
As soon as the type T switches to int instead of string, the counter resets.
Does this fail by design, and if so what is the reason or how can I get around it? Or is it a bug? It makes sense to some degree because the type T, being generic, is in the class declaration, but..
Using a static variable will create one copy of the count variable which will be incremented every time an object of the class is created. All objects of the Counter class will have the same value of count at any given point in time.
Using generics, type parameters are not allowed to be static. As static variable is shared among object so compiler can not determine which type to used. Consider the following example if static type parameters were allowed.
This is because the static variable retains the value after the increment even when the function block ends. Data segments are used to allocate a static variable and not stack segments. Static variables by default have some values with which it is initialized if not explicitly initialized.
Each different T
creates a new class for A<T>
and hence distinct static counters.
To get around this you can use inheritance like so:
abstract class A { protected static int counter; } class A<T> : A { private static int Counter { get { Increment(); return counter; } } private static void Increment() { counter++; } public int Index; public A() { this.Index = Counter; Console.WriteLine(this.Index); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With