Michael
Michael

Reputation: 37

Inherit constants - best style?

This is more of an "is there a better way" question than a real problem.

When having a property that is only accessed in a base class:

 private const bool isSomething = true;

I sometimes have to change this value in a project where I inherit from this class. But as it is a constant and used class-wide, I normally change the code in the base class to something like this:

 private const bool isSomething = true;
 protected virtual bool IsSomething{
       get{
           return isSomething;
       }
 }

And override the property in the subclass and create a new isSomething constant.

This creates a new field and an override and, in my opinion, is not nice style. Is there a better way to do this?

The value is a constant, and it will be constant in the complete project where I'm using it.

Upvotes: 1

Views: 3095

Answers (1)

unholysampler
unholysampler

Reputation: 17321

If you need to set the value based on which class you are in but don't want the value to change later, than const is not the right keyword. Instead, you can use readonly and require sub-classes to pass in a value to the constructor.

The readonly keyword is different from the const keyword. A const field can only be initialized at the declaration of the field. A readonly field can be initialized either at the declaration or in a constructor. Therefore, readonly fields can have different values depending on the constructor used. Also, while a const field is a compile-time constant, the readonly field can be used for runtime constants... Source

Edit:
To summarize: You have a filed that is only accessed by the base class and the base class should never alter that value. In most cases, the default value is fine. However, there are some cases that arise when a subclass need to set it's own value that is different than the default.

class Base {
  private readonly bool _isSomething;

  public Base() : this(false) {}

  protected Base(bool isSomething)
  {
    _isSomething = isSomething;
  }
}
class Child {
  public Child() : base(true) {}
}

This provides the same functionality as your suggested work-around. The value can not be changed and only a child class can provide a different value. It has an added benefit of not allow the child class invalidate the fact that the value is intended to be constant. The override method allows for this:

protected override bool IsSomething{
   get{
     return BOOLEAN_EXPRESSION;
   }
}

I understand your idea of making it a static value (since we know every instance will use the same value), but that only makes things complicated as static items are not inherited.

Upvotes: 3

Related Questions