Minor update to the base class guidelines

Fairly minor update -- as always, let me know if there are questions or
comments.

---------------------------------------------------------

Consider using abstract classes (even if there are no abstract
members) if the class is designed to be a root in an inheritance hierarchy make
this clear by not allowing it to be directly used.  

Annotation (BradAbrams): In
retrospect we should have made System.Exception an abstract
class. System.Exception was meant to be used as a root in the
inheritance hierarchy but because we allowed it to be constructable lazy
developers tend to throw it rather than using a more meaningful exception.

  Avoid
prefixing or postfixing “Base”, “Root” or other such words as this type is
likely to show up in public APIs.  In general base classes have simple,
meaningful, pretty names because they are commonly used in public APIs.  In
some cases differentiation is unavoidable because the base class is really an
implementation detail and not a key design point. For example in
System.Windows.Forms, the ButtonBase class is the base class for Buttons,
CheckBoxes, etc.  In these cases use the XxxBase pattern. 

Do prefer using base types in public signatures
rather than concrete types. This provides better opportunity for substitution
and more flexibility in changing the implementation in the future.

Consider the following
method:

public FileStream GetDataStream() {}

The implementation of
GetDataStream is not locked into being backed by a File. If the
implementation changes to use any other type of stream (such as a NetworkStream)
a breaking change will have to be made. It would be better to use the base
class Stream to gain greater flexibility.

public Stream GetDataStream()
{}

 

Annotation (Brad Abrams) This guideline
could be easily abused to create overly complicated designs. If you have
an API that is meant to only work with files, using a FileStream is the right
thing to do. Don’t push in abstraction unless it is called for.