Inheritance of something like a static field

c# inheritance
c# static inheritance
c# inheritance constructor
c# static class
c# protected inheritance
c# extends
c# extend class with property
c# base class to derived class

this question is a bit more theoretical, it's not a problem which is part of homework or an important project... I'm asking this question because I think this could be quite handy to know, but I couldn't find an approtiate answer.

Problem description:

  • every class which inherits from my abstract class should be forced to provide a Symbol image.

  • the symbols shouldn't be Runtime-changeable

  • instances should not contain an image [to save memory]

  • solutions which inform the developer in runtime [maybe by using reflection], are not acceptable (this is a more theoretical question) .

.

abstract class A
{
    public static abstract Image Symbol{get;}
}
class B:A
{
  //this Field should be forced for every class that inherits from A
  public static override Image Symbol{get{return....}}
}

of course, I could have used instead of static the readonly keyword.

But this would mean that every instance of class B would cause an extra image, because readonly allows fields to be set during runtime in the constructor ...leading to memory waste... maybe not a huge memory waste because there would be a reference waste more or less, but it's still wasting stuff... [Correct me if I'm wrong.]

So... how is this easy and nice possible by using inheritance rules?


Are static variables inherited, are shared among the subclasses of the base class. First, some say static members are not inherited, but they are inherited according to the Java language specification. And if they weren't, "protected static" would make no sense. My mental model of inheritance implies that when a subclass inherits a static field from the superclass, a new copy is formed! I know this is not correct.


You can cache your images by key in a dedicated class and just provide a key for each inherited class :

public class ImageManager
{
    private static Dictionary<string, Image> _images = new Dictionary<string, Image>();
    private static object _locker = new object();
    public static Image GetImageByTypeKey(string key)
    {
        if (!_images.ContainsKey(key))
        {
            lock (_locker) {
                if (!_images.ContainsKey(key))
                {
                    //Add your real loading logic here + handle exceptions (not found, etc...)
                    Image image = Image.FromFile(key + ".png");
                    _images.Add(key,image);
                }
            }
        }
        return _images[key];
    }
}

public abstract class BaseType
{
    public Image Symbol
    {
        get
        {
            return ImageManager.GetImageByTypeKey(SymbolKey);
        }
    }
    protected abstract string SymbolKey { get;  }
}

public class TypeA : BaseType
{
    protected override string SymbolKey
    {
        get { return "TypeA";}
    }
}

Linxutopia - Thinking in C++, , all the other overloaded functions in the base class are hidden. It was for this reason that was trying to use an inherited static field; since every Animal has a Food, it seemed to make sense to create it as a property of Animal, just like you would for Weight, rather than creating it individually in each sub-class.


I know it's an old question, but i just playing around with static fields and inheritance and want to share my results. In my current project i got a complex data structure in semiconductor context... So my examples wont fit to the question but could properly demonstrate how to realize some kind of static field inheritance.

so here are my workarounds:

First workaround (using generics):

public abstract class TESTAbstract 
{
    //overall list of elements
    public static List<TESTAbstract> Elements = new List<TESTAbstract>();
    public static int Count { get; private set; }
    public int localId { get; protected set; }
    public int globalId { get; protected set; }

    //members here
    public int someValue = 0;

    public TESTAbstract()
    {
        globalId = Count; Count++;
        Elements.Add(this);
    }
}



public abstract class TESTAbstract<T> : TESTAbstract where T : TESTAbstract
{
    new public static List<T> Elements = new List<T>();
    new public static int Count { get; private set; }

    public TESTAbstract()
        : base()
    {
        localId = Count; Count++;
        Elements.Add(this as T);
    }
}

The implementation looks like:

public class TEST1 : TESTAbstract<TEST1>
{
    public TEST1(int i)
        : base()
    {
        this.someValue = i;
    }

}

public class TEST2 : TESTAbstract<TEST2>
{
    public TEST2(int i)
        : base()
    {
        this.someValue = i;
    }

}

Usage:

            TESTAbstract test1 = new TEST1(1001);
            TESTAbstract test2 = new TEST2(1002);
            TESTAbstract test3 = new TEST2(1003);
            TESTAbstract test4 = new TEST1(1004);
            TESTAbstract test5 = new TEST1(1005);
            TESTAbstract test6 = new TEST1(1006);
            TESTAbstract test7 = new TEST2(1007);
            TESTAbstract test8 = new TEST1(1008);

            Console.WriteLine("All StructureItem Elements: " + TESTAbstract.Elements.Count);
            foreach (var item in TESTAbstract.Elements)
            {
                Console.WriteLine("someValue: " + item.someValue + " localId: " + item.localId + " globalId: " + item.globalId);
            }

            Console.WriteLine("TEST1 Elements: " + TEST1.Elements.Count);
            foreach (var item in TEST1.Elements)
            {
                Console.WriteLine("someValue: " + item.someValue + " localId: " + item.localId + " globalId: " + item.globalId);
            }

            Console.WriteLine("TEST2 Elements: " + TEST2.Count);
            foreach (var item in TEST2.Elements)
            {
                Console.WriteLine("someValue: " + item.someValue + " localId: " + item.localId + " globalId: " + item.globalId);
            }

Output:

All StructureItem Elements: 8
someValue: 1001 localId: 0 globalId: 0
someValue: 1002 localId: 0 globalId: 1
someValue: 1003 localId: 1 globalId: 2
someValue: 1004 localId: 1 globalId: 3
someValue: 1005 localId: 2 globalId: 4
someValue: 1006 localId: 3 globalId: 5
someValue: 1007 localId: 2 globalId: 6
someValue: 1008 localId: 4 globalId: 7
TEST1 Elements: 5
someValue: 1001 localId: 0 globalId: 0
someValue: 1004 localId: 1 globalId: 3
someValue: 1005 localId: 2 globalId: 4
someValue: 1006 localId: 3 globalId: 5
someValue: 1008 localId: 4 globalId: 7
TEST2 Elements: 3
someValue: 1002 localId: 0 globalId: 1
someValue: 1003 localId: 1 globalId: 2
someValue: 1007 localId: 2 globalId: 6

The second workaround is using interfaces. This is usefull when you already inherit from some class and want to add static fields.

public abstract class Class2 
{
    public int someValue { get; set; }
}


public class TEST3 : Class2, ITest
{
    public TEST3()
    {
        this.AddObj();

    }

}

public class TEST4 : Class2, ITest
{
    public TEST4()
    {
        this.AddObj();
    }

}

public interface ITest{}

I used then a generic extension method for the interface

public static class Class2Ex
{
    public static void AddObj<T>(this T obj) where T : ITest
    {
        ITest<T>.Instances.Add(obj);
    }
    //Alternative:
    public static List<T> GetOtherInstances<T>(this T obj) where T : ITest
    {
        return ITest<T>.Instances;
    }
}

public static class ITest<T> where T : ITest
{
    public static List<T> Instances = new List<T>();
}

Example:

            TEST3 aTest1 = new TEST3();
            TEST3 aTest2 = new TEST3();
            TEST3 aTest3 = new TEST3();
            TEST3 aTest4 = new TEST3();

            TEST4 aTest5 = new TEST4();
            TEST4 aTest6 = new TEST4();

            Console.WriteLine("TEST4: " + ITest<TEST4>.Instances.Count);
            Console.WriteLine("TEST3: " + ITest<TEST3>.Instances.Count);

C# Inheritance, These nuclei act like tiny magnets. These tiny magnets, in the presence of a static magnetic field, change their orientation to align with the static field and spin at  BTW, regarding public static readonly fields, I don't have much bad to say about them, and I don't think they should be avoided out of hand. C# In Depth states that using a public static readonly field for the instance member of a singleton (or here, a multiton) is not only fully thread-safe, it's reasonably lazy when used as a true singleton.


I would create a static constructor in the derived classes.

abstract class A {
  public Image Symbol { get; protected set; }
}
class B:A {
  private static Image SymbolInstance { get; private set; }
  static B() {
    // SymbolInstance = ...
  }
  public B() {
    Symbol = SymbolInstance;
  }
}

The static constructor only gets called a single time when the first instance of class B is initiated. It doesn't matter if you initiate 20 instances.

One detail that would have to be tested: would there be any reference conflict of the static field in Class A when being set from several derived classes, or would each derived class have its own separate instance? I think it should be fine but you'd have to test it.

If you want to enforce the derived class to set the field, you can do a validation in the base class and throw an exception if the value is missing.

Why does C# doesn't support Multiple inheritance, Declaring a local class in a static or a non - static block , influences what the class This inherited field is accessed in the NonStaticLocal class as shown at ( 6 )  Static constants are exactly like static fields except that their values cannot be changed. In the field declaration, the final and staticmodifiers are both used. For example, perhaps the Item class should impose a restriction on the length of the itemName. We could create a static constant maxItemNameLength:


Inherited Metabolic Epilepsies, I'd like for each enemy subtype to have a static "count" variable, so that I can I'm not even 100% sure that static inheritance like I'm trying to do is possible in C#. and opinions because maybe I don't know many things that I should know. Static classes are sealed and therefore cannot be inherited. They cannot inherit from any class except Object. Static classes cannot contain an instance constructor. However, they can contain a static constructor.


A Programmer's Guide to Java Certification: A Comprehensive Primer, We can have Static (or shared) methods,properties and fields. that doesn't have the same behavior as inheritance(it breaks polymorphism). In addition to the normal types a type can inherit from, any type in the list can be prepended with the static keyword which turns inheritance into composition. A field is added to the type with the specified type, and all public instance and explicit interface implementation methods, properties, and events from the inherited type are copied to the inheriting type and proxied to the field:


A question about inheritance and static variables : csharp, A class C may be declared as a subclass of class B by an extends-clause of the The declaration of C may hide a non-static field f inherited from B by declaring​  In each object of a class will have its own copy of all the fields of the class. However, in certain situations, it may be required to share a common copy of fields among all the objects of the same class. This is accomplished by declaring the field (s) to be static and such fields are known as static field (s).