-1

I have a set of classes which should all have a static string member. Let's call it TABLENAME. The base class ClassA<T>, a templated class, for all of these classes has a protected static string member called TABLENAME. Because of how dotnet handles static members for templated classes, each derived class gets its own instance of the static member. In addition, each class has it's own static constructor which sets TABLENAME. So far so good.

The issue I'm having is twofold.

  1. Subclasses of ClassA appear to be able to access TABLENAME for other subclasses. i.e. ClassAB can reference ClassAC.TABLENAME.
  2. Accessing ClassAC.TABLENAME from ClassAB does not trigger the static constructor in ClassAC.

Are there any good patterns for giving a set of classes a set of static members where each derived class has it's own set of values, and there is no way to access these values before they have been set.

Right now I can get around the issue by adding a non-static method to the base class called Tablename(), which returns the static string member TABLENAME. In the cases where ClassAB needs access to the TABLENAME from ClassAC, I can create an instance of ClassAC and call Tablename(). This will trigger the static constructor of ClassAC. I don't like this solution because you can accidentally access ClassAC.TABLENAME directly, which will return null, since it does not trigger static constructor for ClassAC.

The reason I want a set of static members is that I don't want to initialize these fields more than once per derived class.

Thoughts, ideas?

bpeikes
  • 3,495
  • 9
  • 42
  • 80
  • NB: "Templated" is a C++ term. C# has "Generics", i.e. a "generic" class, which is subtly different. – canton7 Aug 14 '23 at 16:43
  • 1
    "*Accessing `ClassAC.TABLENAME` from `ClassAB` does not trigger the static constructor in `ClassAC`.*" -- [are you sure about that?](https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUHqAUwHcACAYQBsBDAZ1oEEAhACgEoA6AFUNuHYDcePKgDMpDBRr0GAHi4A+PAG88pdRPGpMANgmYADKS7MAMgFEAcgwCy5obg2k1G7Xqp1G7F+tWOnrpgAnCwARB4ypADGUcAA9mChbA4BGiZMFtZ2pAC8pKEAZnFxoSkaAL54lfi4YhLoUp7MpCCNMrIAllDASrh+Tm5tjKxsPqT9qfoh4dLD0bEJraGkiMZmVrbmyWPVY3WoACzGvPyj/r5jA8Es6Zmb2+ek1eVAA) A [mcve] would be very useful to figure out exactly what you're doing and seeing. – canton7 Aug 14 '23 at 16:45
  • 4
    OP, it's likely that you're doing something wrong, but I can't tell what because you didn't show any code. Show your code please. – John Wu Aug 14 '23 at 16:46
  • Is `TABLENAME` private or public/protected? – Jay Buckman Aug 14 '23 at 16:55

1 Answers1

0

By design, the static members of the Declaring Class are shared amongst all the subclasses. So your TABLENAME static member in ClassA will be shared amongst all its sub-classes. (Credits: https://stackoverflow.com/a/5851501/17985195)


To address your issue,

The reason I want a set of static members is that I don't want to initialize these fields more than once per derived class.

You can make use of Auto-Properties with an initial value.

So in your derived class, set your member like:

public string TABLENAME { get; set; } = "Initial Table Name"; // C# 6 or higher

This way, when that subclass is instantiated, your TABLENAME field is initialized with "Initial Table Name" and you can make that unique to everyone of your subclasses, which is essentially what you wanted.

TP95
  • 175
  • 8