Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to override constants derived classes?

Tags:

c#

CODE :

public class A {
    public const int beingSupportedRate = 0;
}

 public partial class B : A {
    public const int beingSupportedRate = 1;

}

I want it as explicitly as a const int because of performance. Putting virtual in front of class A variable beingSupportedRate causes compiler error following :

The modifier 'virtual' is not valid for this item

like image 813
Mohsen Sarkar Avatar asked Mar 01 '13 13:03

Mohsen Sarkar


3 Answers

You should use the new keyword to explicitly hide the inherited member:

public class A
{
    public const int beingSupportedRate = 0;
}

public class B : A
{
    public new const int beingSupportedRate = 1;
}

Remember that you cannot access the constant member from an instance.

Console.WriteLine(A.beingSupportedRate);
Console.WriteLine(B.beingSupportedRate);

Output:

0
1

There are some problems that you should consider when using this solution. Take the following console program, for example:

class Program
{
    static void Main(string[] args)
    {
        A a = new A();
        B b = new B();
        C c = new C();

        a.GetBeingSupportRate();
        b.GetBeingSupportRate();
        c.GetBeingSupportRate();

        Console.Read();
    }

    public class A
    {
        public const int beingSupportedRate = 0;
        public void GetBeingSupportRate()
        {
            Console.WriteLine(beingSupportedRate);
        }
    }

    public class B : A
    {
        public new const int beingSupportedRate = 1;

    }

    public class C : B
    {

    }
}

This will output 0 for all three class instances, since the inherited method uses the constant value in A. This means you will have to override all methods that reference the constant.

A preferred approach is to use an interface with a property that must be implemented and not use constants for this purpose.

like image 92
John Willemse Avatar answered Oct 28 '22 14:10

John Willemse


Fields (including constants) can't be virtual. That has nothing to do with it being a constant... it's just the way fields work... although the fact that constants are implicitly static makes it even less feasible, as it were.

If you want polymorphic behaviour, it has to be via an instance member which is a property, method or event.

As an aside, I strongly suspect your "I want it as const for performance reasons" justification is bogus micro-optimization. It's not even clear how you're using this, but I very much doubt that you've tried it as a non-constant and proved that it's too slow.

like image 42
Jon Skeet Avatar answered Oct 28 '22 13:10

Jon Skeet


Actually I believe you misunderstood the point of polymorphism in object-oriented programming.

Constants, fields and variables are just a storage (well, references, but I'm talking from the conceptual point of view).

Polymorphism is about changing the behavior of something. Overriding a constant couldn't be changing a behavior but changing its value.

Another point is a constant is static, thus it doesn't belong to an instance but there's an immutable single value in the AppDomain and it survives for the application life-cycle.

With the above statement, why you would want to override a constant like an instance member? Do you imagine the next situation?

public class A 
{
      public virtual const int Some = 1;
}

public class B : A
{
      public override const int Some = 2;
}

public class C : A
{
     // No override here!
}

int valueOfSomeConstant = C.Some;

Hold! If a constant is static, C.Some would be 2 even if C does override no constant!

Some quote from your question:

I want it as explicitly as a const int because of performance. [...]

This has only an answer: the premature optimization is the devil of any software development.

As Jon Skeet said, this is going to be the least of your issues.

like image 23
Matías Fidemraizer Avatar answered Oct 28 '22 14:10

Matías Fidemraizer