Marking the class sealed/NotInheritable is the easiest way to correct this violation.
Note: This approach has the side-effect that you will not be able to use any virtual methods in your class.
Lazy Initialization
An alternative is to only call the virtual method on-demand. This can be accomplished by providing the resources that are dependant on the virtual method to a class and/or its derived types via public or protected properties on the base class. The properties can check whether the resources have been initialized. If they haven't, the property can call the virtual method once, caching the result for subsequent access.
Example
Lazy initialization is commonly found in abstract classes where the need exists to give derived types a chance to strong-type a property defined on the base class. Along with generics in the 2.0 framework, a solution can be devised that is type-safe and doesn't require a virtual method call in the constructor:
class abstract Car<TEngine>
{
private TEngine engine;
public TEngine Engine
{
get
{
// create the engine if it's a null reference
return engine ?? engine = CreateEngine();
}
}
protected abstract TEngine CreateEngine();
}
class Lemon : Car<BrokenEngine>
{
protected override BrokenEngine CreateEngine()
{
return new BrokenEngine();
}
}
In the example above, the engine field is initialized by the return value of the virtual CreateEngine method, which is only called the first time the Engine property is accessed (unless the CreateEngine method returns null , in which case it will be called again each time the Engine property is accessed until a non-null value is returned).