1

I have a question similar to this one: Can I have a base class where each derived class has its own copy of a static property?, but the answer there didn't seem very conclusive to me.

Basically, I have a class that has a constant property, and I want to derive a class that has all the same methods but uses a different value for the variable. For a simple analogy, imagine that I had a class that looked, in part, like this:

public class Triangle
{
    public const NumSides = 3;
    int sideLength;

    public int Perimeter()
    {
        return NumSides * sideLength;
    }
}

and now I wanted to make a Square class that was exactly like the Triangle class, except NumSides was now 4.

In other words, I want a class that now looks, in its entirety, something like:

public class Square : Triangle
{
    public const NumSides = 4;
}

but that still has access to all the methods of the Triangle class. (I can handle writing a new constructor if necessary, but I don't want to have to copy over the dozen or so methods from the original class. They're all supposed to behave exactly the same, but with NumSides now having a value of 4.)

I can't figure out how to do this, either with NumSides being a const or as a static property with only a get function. If I try to override the constant, I get "The modifier 'override' is not valid for this item." When I try to override the static property version, I get the message equivalent of "A static member Triangle.NumSides cannot be marked as override, virtual, or abstract."

And, yes, I've tried creating a Shape class, putting all the functionality in there, and then having both Triangle and Square inherit from that class. I run into the same problem with NumSides though. How can I change the effective value of a constant or static variable/property when deriving a new class?

Community
  • 1
  • 1
Galendo
  • 163
  • 1
  • 5

2 Answers2

4

And, yes, I've tried creating a Shape class, putting all the functionality in there, and then having both Triangle and Square inherit from that class.

This is the right approach. A Square is not a Triangle, and shouldn't subclass it.

I run into the same problem with NumSides though. How can I change the effective value of a constant or static variable/property when deriving a new class?

You can't use static variables. You need to use non-statics, though they can be properties backed by a local constant if you chose. That being said, given the simplicity here, I'd just do:

public abstract class Shape
{
   public abstract int NumSides { get; }
   // Other functionality...
}

Override via:

public override int NumSides { get { return 3; } } // For triangle
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • This is good, thank you. The only problem is that it completely messes up most of my static methods, since I can't now reference the constant in those methods anymore. That's a little beyond the scope of the question I asked, but it is a significant side effect to this solution, which does bear mentioning. – Galendo Jul 15 '14 at 02:36
1

To override the member it has to be virtual, and a constant or static can't be virtual. Make it a property instead:

public class Triangle
{
    public virtual int NumSides { get { return 3; } }

    int sideLength;

    public int Perimeter()
    {
        return NumSides * sideLength;
    }
}

public class Square : Triangle
{
    public override int NumSides { get { return 4; } }
}

The same approach would work for a Shape class, but you might want to make it abstract insetad of virtual to avoid having an implementation of the property in the Shape class.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005