Overrides of Method() should call base.Method()
Overrides should refine or complete the base method behavior; not calling the base method replaces it instead. Violations signal a design flaw, especially when the design justifies replacing rather than refining.
How to fix
Investigate whether inheritance is the right choice, or whether exposing the method polymorphically through an interface would be better. The template method pattern http://en.wikipedia.org/wiki/Template_method_pattern might help.
CQLinq source
This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.
// <Name>Overrides of Method() should call base.Method()</Name>
// <Id>ND1204:OverridesOfMethodShouldCallBaseMethod</Id>
warnif count > 0
from t in Types // Take account of third-party base classes also
// Bother only classes with descendant
where t.IsClass && t.NbChildren > 0
from mBase in t.InstanceMethods
where mBase.IsVirtual &&
!mBase.IsThirdParty &&
!mBase.IsAbstract &&
!mBase.IsExplicitInterfaceImpl &&
!mBase.IsPropertyGetter &&
!mBase.IsPropertySetter &&
!mBase.IsIndexerGetter &&
!mBase.IsIndexerSetter &&
// Don't take account of virtual methods of the Object type.
!mBase.Name.EqualsAny("Equals(Object)","ToString()", "GetHashCode()","Finalize()") &&
mBase.NbLinesOfCode >= 5 && // Need a sufficient behavior to refine
JustMyCode.Contains(mBase)
from mOverride in mBase.OverridesDirectDerived
where !mOverride.IsUsing(mBase) &&
JustMyCode.Contains(mOverride) // Don't warn on generated code
select new {
mOverride,
shouldCall = mBase,
definedInBaseClass = mBase.ParentType,
Debt = 10.ToMinutes().ToDebt(),
Severity = Severity.Medium
}
//<Expl>
// The *override {0}* might need to invoke the base method it overrides to *refine* its base behavior.
//</Expl>
//<Desc>
// Overrides should **refine** or **complete** the base method behavior; not
// calling the base method *replaces* it instead. Violations signal a *design
// flaw*, especially when the design justifies replacing rather than refining.
//</Desc>
//<HowToFix>
// Investigate whether *inheritance* is the right choice, or whether exposing
// the method polymorphically through an interface would be better. The
// **template method** pattern
// http://en.wikipedia.org/wiki/Template_method_pattern might help.
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
Object Oriented Design: all 14 items
- Avoid interfaces too big ND1200
- Base class should not use derivatives ND1201
- Class shouldn't be too deep in inheritance tree ND1202
- Class with no descendant should be sealed if possible ND1203
- Overrides of Method() should call base.Method() ND1204
- Do not hide base class methods ND1205
- A stateless class or structure might be turned into a static type ND1206
- Non-static classes should be instantiated or turned to static ND1207
- Methods should be declared static if possible ND1208
- Constructor should not call a virtual method ND1209
- Avoid the Singleton pattern ND1210
- Don't assign static fields from instance methods ND1211
- Avoid empty interfaces ND1212
- Avoid types initialization cycles ND1213