Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I'm just running NDepend against some code that I have written and one of the warnings is Overrides of Method() should call base.Method().

The places this occurs are where I have a base class which has virtual properties and methods with default behaviour but which can be overridden by a class which inherits from the base class and doesn't call the overridden method.

For example, in the base class I have a property defined like this:

protected virtual char CloseQuote
{
    get
    {
        return '"';
    }
}

And then in an inheriting class which uses a different close quote:

protected override char CloseQuote
{
    get
    {
        return ']';
    }
}

Not all classes which inherit from the base class use different quote characters hence my initial design.

The alternatives I thought of were have get/set properties in the base class with the defaults set in the constructor:

protected BaseClass()
{
    this.CloseQuote = '"';
}

protected char CloseQuote { get; set; }

public InheritingClass()
{
    this.CloseQuote = ']';
}

Or make the base class require the values as constructor args:

protected BaseClass(char closeQuote, ...)
{
    this.CloseQuote = '"';
}

protected char CloseQuote { get; private set; }

public InheritingClass()
    base (closeQuote: ']', ...)
{
}

Should I use virtual in a scenario where the base implementation may be replaced instead of extended or should I opt for one of the alternatives I thought of? If so, which would be preferable and why?

share|improve this question

migrated from codereview.stackexchange.com Dec 2 '12 at 16:38

This question came from our site for peer programmer code reviews.

add comment

3 Answers 3

up vote 3 down vote accepted

It is a valid design decision to have a default implementation of a method in a base-class that should be completely replaced when the method is overridden in a derived class.

Thus, you could regard the warnings from NDepend as a false-positive for your code. I would check the NDepend documentation to see if there is an option or source-code annotation that tells NDepend that not calling the base-class implementation is correct here to get rid of the clutter.

If there is no such option (or it does not work for properties), my preference would be the first alternative (overriding the value of CloseQuote in the derived-class' constructor).

share|improve this answer
add comment

It's a strange warning NDepend gives you. Surely not all overridden methods have a need to call the base method, so I think the text Method() should call base.Method() is too strong. It does make it look like you may be doing something wrong, which you clearly are not.

This has nothing to do with using virtual though. Was that supposed to be a different question?

share|improve this answer
    
What do you mean by it having nothing to do with virtual? –  Trevor Pilley Dec 2 '12 at 17:09
    
I mean the choice between using virtual or not is a different decision, for a different situation, than the choice of calling the base method in the derived one. I don't see how the one decision influences the other. –  Mr Lister Dec 2 '12 at 17:18
add comment

The warning is trying to tell you that, since you've defined an is-a relationship with the super class, all protected and public behavior of the super class should be reachable from the subclass.

Most often the real reason you want to override a method to replace its behavior completely is a demand for composition. E.g. instead of overriding the method closeQuote, you might want to create an interface 'QuoteDefinitionProvider' (or such like) and feed it to the superclass.

Other reasons might be:

  • super class should be abstract, but isn't, so a 'default' implementation is given. Solution: make super class abstract.
  • subclass implementation can be optimized for the special case. This seems to be a sound reason to completely override the method and not call super.

So, before ignoring this warning, check whether your situation demands composition instead of inheritance. In my professional experience, I've seldom found a true need for class inheritance.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.