Static fields in a base class and derived classes
Asked Answered
T

3

61

In an abstract base class if we have some static fields then what happens to them ?

Is their scope the classes which inherit from this base class or just the type from which it is inheriting (each subclass has it's own copy of the static field from the abstract base class)?

Totalizator answered 1/5, 2011 at 21:20 Comment(2)
BTW, the fact that the base class is abstract is a red herring; it doesn't matter if the base class is abstract or not, the behavior @Marc Gravell points out is the same.Hilly
@casperOne: I was looking for something like TypeLocal<T> as we have ThreadLocal<T> so any object of that type would be static in it's corresponding subclass.Totalizator
A
88

static members are entirely specific to the declaring class; subclasses do not get separate copies. The only exception here is generics; if an open generic type declares static fields, the field is specific to that exact combination of type arguments that make up the closed generic type; i.e. Foo<int> would have separate static fields to Foo<string>, assuming the fields are defined on Foo<T>.

Assiniboine answered 1/5, 2011 at 21:21 Comment(6)
@Marc Gravell: Sorry man, you and @Jon Skeet taught me to be pedantic; you meant to say "type arguments" as opposed to "static arguments". =) Hope all is well across the pond.Hilly
The how to declare a unique variable for all instances (per type) from base class ?Totalizator
@Xaqron: You can't, you would have to redeclare the static member you want on each derived class.Hilly
@Marc Gravell: Being even more pedantic, it's casp e rOne, not casp a rOne =)Hilly
@Hilly - indeed; I blame iPod; it doesn't make things easy ;p For the record, I know the spelling - 'twas just a typoAssiniboine
It would be useful to have an access modifiers that allow that.Byrnie
S
20

As pointed out in other answer, the base class static field will be shared between all the subclasses. If you need a separate copy for each final subclass, you can use a static dictionary with a subclass name as a key:

class Base
{
    private static Dictionary<string, int> myStaticFieldDict = new Dictionary<string, int>();

    public int MyStaticField
    {
        get
        {
            return myStaticFieldDict.ContainsKey(this.GetType().Name)
                   ? myStaticFieldDict[this.GetType().Name]
                   : default(int);
        }

        set
        {
            myStaticFieldDict[this.GetType().Name] = value;
        }
    }

    void MyMethod()
    {
        MyStaticField = 42;
    }
}
Stratovision answered 19/8, 2015 at 23:52 Comment(0)
S
1

The following code illustrates that the static member's value is shared among the instantiation of the abstract generic of the same type. Like in the example below all instantiations with generic type 'int' would share one static value, all 'string's another value. I was initially thinking that it would be shared among all instantiation agnostic to the generic type, but turned out that's not the case.

using System;
using System.Collections.Generic;
using System.Linq;

abstract class AbstractGeneric<T>
{
    private static int sharedCounter = 0;

    public AbstractGeneric()
    {
        sharedCounter++;
    }
    
    public int GetCounterValue()
    {
        return sharedCounter;
    }
}

class GenInt : AbstractGeneric<int> {}
class GenInt2 : AbstractGeneric<int> {}
class GenStr : AbstractGeneric<string> {}

public class Program
{
    public static void Main()
    {
        var instance1 = new GenInt();
        var instance2 = new GenStr();
        var instance3 = new GenInt2();
        var instance4 = new GenInt();

        Console.WriteLine(instance1.GetCounterValue()); // Output: 3
        Console.WriteLine(instance2.GetCounterValue()); // Output: 1
        Console.WriteLine(instance3.GetCounterValue()); // Output: 3
        Console.WriteLine(instance4.GetCounterValue()); // Output: 3
    }
}
Sneer answered 17/8, 2023 at 14:31 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.