Dec 25

C# – Alternative to overriding static variables

Tag: .NET,C#,ProgrammingAbhijeet Maharana @ 9:22 pm

In a recent project, I came across a peculiar requirement.

Modified version of the requirement:
1. Define a static variable in base class (say Code)
2. Define a property in base class that accesses Code (say Message)
3. Modify the value of Code in derived class
4. BaseInstance.Message should access the value of Code defined in base class whereas DerivedInstance.Message should access the one defined in derived class.

So I tried the following

namespace StaticTest
{
    class Base
    {
        protected static int Code = 1;
 
        public String Message
        {
            get
            {
                switch (Code)
                {
                    case 1:
                        return "One";
 
                    case 2:
                        return "Two";
 
                }
 
                return "Default";
            }
        }
    }
 
    class Derived : Base
    {
        protected static new int Code = 2;
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Base.Message: " + new Base().Message);
            Console.WriteLine("Derived.Message: " + new Derived().Message);
 
            Console.Read();
        }
    }
}

This did not work and the output was

Base.Message: One
Derived.Message: One

Turns out that Message needs to be redefined in Derived to be able to access the new value of Code. With a lot of derived classes, this was impractical and Message’s getter was a bit more involved than what I have written above.

I found a neat solution by Dave Booker posted here.

Define a custom attribute class

[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class CodeAttribute : Attribute
{
        public int Code;
        public CodeAttribute(int code)
        {
            Code = code;
        }
}

Then define attribute values for the 2 classes:

[CodeAttribute(1)]
class Base
{ ... }
 
[CodeAttribute(2)]
class Derived
{ ... }

Now delete the Code property from the classes and modify Message to retrieve the code like this:

public String Message
{
	get
        {
                int Code = ((CodeAttribute) Attribute.GetCustomAttribute(this.GetType(), typeof(CodeAttribute))).Code;
 
                switch (Code)
                {
                    case 1:
                        return "One";
 
                    case 2:
                        return "Two";
 
                }
 
                return "Default";
         }
}

This returned the values as expected. If the derived class is not supplied with an attribute value, it just inherits the value from its parent. So not exactly a static variable but it behaves like one that can be inherited and overriden if necessary. Quite elegant!

The original requirement was to eliminate any instances of both classes. This meant Message had to be a static property. I haven’t been able to figure out how to do that … specifically how to replace “this.GetType()” with something static that returns which class the property was invoked with rather than the class which it was defined in (which is what the reflection based methods do).

Any ideas? Other than getting into IL code to see if and how this can be done?

One Response to “C# – Alternative to overriding static variables”

  1. kettaneh says:

    Really nice post . I appreciate your work

Leave a Reply