Skip to content

Latest commit

 

History

History
63 lines (53 loc) · 2.26 KB

QW0005.md

File metadata and controls

63 lines (53 loc) · 2.26 KB

QW0005: Seal concrete classes unless designed for inheritance

Inheritance is one of the pillars of Object Oriented Programming. Designing a class to support inheritance however, is hard. As a consequence, it is considered a bad practice to unintentionally allowing a class to be inheritable.

Design challenges

By allowing inheritance one must consider the consequences of derived classes changing the state initialization, as it might effect method and (calculated) property calls that not longer rightfully assume their preconditions to be met.

Things like equality (if not by reference), serialization, and projections become less straightforward. This can all be solved of course, but it requires effort. If you're not willing to put in this effort (yet); seal the class.

By sealing a class, the code also tells a story: as far as this code base is concerned: this concept is fully covered by this class, no detail (relevant to the application) is left out.

Performance

Calling virtual methods and properties have a small performance penalty. This is due to the fact that the CLR has to check the type runtime in order to determine which type defines the method/property. In sealed classes the JIT compiler can treat virtual methods and properties of sealed classes as non-virtual ones, bypassing the CLR runtime check. In other words, there is a small performance gain in sealing a class.

Designed for inheritance

According to this rule, a (concrete) class is considered to be designed for inheritance when:

  1. It defines at least one virtual member
  2. It defines at least one protected member
  3. It is decorated with a [Inheritable] attribute (name convention based)

Attributes

Attributes are excluded from this rule. Not because they should not be sealed, but because Microsoft's CA1813 handles that case already. It prevents duplicate reports.

Non-compliant

public class Noncompliant
{
}

Compliant

public class Compliant
{
    protected object Method() { } // any protected member
}

public class Compliant
{
    public virtual object Method() { } // any virtual member
}

[Inheritable] // Name convention based way to decorate a class
public class Compliant
{
}