On Designing Good Libraries — Part II


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">You asked for it, you got it..
feedback always welcome.


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="mso-bidi-font-weight: normal"> style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: normal"> 


style="mso-bidi-font-weight: normal"> style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: normal">Attribute
Usage


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l14 level1 lfo1; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Suffix with
“Attribute”


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l14 level1 lfo1; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Perf tip: seal attribute
classes for faster runtime lookup


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l14 level1 lfo1; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Specify the AttributeUsage attribute
completely


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l14 level2 lfo1; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Don’t rely on the
defaults!


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l14 level2 lfo1; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Be as restrictive as
possible


style="MARGIN: 0in 0in 0pt 1.5in; TEXT-INDENT: -0.25in; mso-list: l14 level3 lfo1; tab-stops: list 1.5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">You can always open it up
later


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">[AttributeUsage(
style="mso-tab-count: 1">     
AttributeTargets.All,
style="mso-tab-count: 1">      Inherited = true,

     
AllowMultiple = false)]


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l14 level1 lfo1; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Arial">AttributeTargets face=Arial size=2> – where is
the attribute allowed to be applied?


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l14 level1 lfo1; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Arial">Inherited face=Arial size=2> – should
derived members/types be considered to have this
attribute?


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l14 level1 lfo1; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Arial">AllowMultiple face=Arial size=2> – Is it
legal to put more than one instance of the attribute on a particular
member?


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l2 level1 lfo2; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Use constructor arguments for
required parameters (positional arguments)


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l2 level2 lfo2; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Provide a read-only property with
the same name


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l2 level1 lfo2; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Use read-write properties for
optional parameters (named arguments)


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l2 level1 lfo2; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Never use overloaded
constructors


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">[AttributeUsage(AttributeTargets.All,
AllowMultiple=true,
style="mso-tab-count: 3">                 
 Inherited=false)]
public
class NameAttribute : Attribute {
style="mso-spacerun: yes">   public NameAttribute (string
userName) {..}
   public
string UserName {get {..}}
  
public int Age {get {..} set{..}}
} //end
class


size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: Arial"> 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Usage:


style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">[NameAttribute(“ size=2>Bob“,
Age=87)]


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">UserName – positional argument


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Age – named
argument


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="mso-bidi-font-weight: normal"> style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Arial; mso-bidi-font-weight: normal">Static
Classes


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l13 level1 lfo3; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Static classes contain just static
members


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l13 level1 lfo3; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Compromise between pure OO design
with usability


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l13 level1 lfo3; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Commonly used
for


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l13 level2 lfo3; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Shortcuts for other operations
(System.IO.File)


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l13 level2 lfo3; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Functionality for which a full OO
wrapper is unwarranted (System.Environment)


size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: Arial"> 


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">public
sealed class Environment 
{


size=2> style="mso-spacerun: yes">  private Environment(){} //prevents
creation


size=2> style="mso-spacerun: yes">  public static void Exit(int exitCode)
{..}


size=2> style="mso-spacerun: yes">  public static int ExitCode
{


size=2> style="mso-spacerun: yes">    get
{..}


size=2> style="mso-spacerun: yes">    set
{..}


size=2> style="mso-spacerun: yes">  }


size=2> style="mso-spacerun: yes">  public static string CommandLine
{


size=2> style="mso-spacerun: yes">    get
{..}


size=2> style="mso-spacerun: yes">  }


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">}


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l5 level1 lfo4; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Best used
when:


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l5 level2 lfo4; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Clear charter for the
class


style="MARGIN: 0in 0in 0pt 1.5in; TEXT-INDENT: -0.25in; mso-list: l5 level3 lfo4; tab-stops: list 1.5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Not a “miscellaneous”
bucket


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l5 level2 lfo4; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Not the center point of a
design


style="MARGIN: 0in 0in 0pt 1.5in; TEXT-INDENT: -0.25in; mso-list: l5 level3 lfo4; tab-stops: list 1.5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Use
sparingly


style="MARGIN: 0in 0in 0pt 1.5in; TEXT-INDENT: -0.25in; mso-list: l5 level3 lfo4; tab-stops: list 1.5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Watch out for disconnected
design


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l5 level1 lfo4; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Static
classes


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l5 level2 lfo4; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Are
sealed


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l5 level2 lfo4; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Have private default
constructor


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l5 level2 lfo4; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">No instance
members


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l5 level1 lfo4; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Static Classes: Bad
Design


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l5 level2 lfo4; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Late in the final milestone we added
a method to tell if the runtime is being shut down


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l5 level2 lfo4; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">However we added the method as an
instance method making it completely uncallable


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l5 level2 lfo4; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">public sealed class Environment {

style="FONT-SIZE: 10pt; FONT-FAMILY: 'Courier New'; mso-bidi-font-family: Arial"> style="mso-spacerun: yes">   private Environment()
{} //Prevent creation
  
// —snip—
   public bool HasShutdownStarted {

      get {
return nativeHasShutdown(); }
   }
   public
static string UserName { get {…} }
style="mso-spacerun: yes">   private static extern bool
nativeHasShutdown();
   //
—snip—
}
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l5 level2 lfo4; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Arial">Constructors face=Arial size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l9 level1 lfo5; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Do minimal work in the
constructor


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l9 level2 lfo5; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Only capture the
parameters


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l9 level2 lfo5; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Cost is delayed


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l9 level1 lfo5; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">You can throw exceptions from
constructors


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l9 level1 lfo5; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Be consistent in the ordering and
naming of constructor parameters


size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">public class
Foo  {
style="mso-spacerun: yes">   private const string defaultA =
“..”;
   private const
string defaultB = “..”;
  
public Foo():
style="mso-tab-count: 1">     
this(defaultA,defaultB) {}
style="mso-spacerun: yes">   public Foo(string a):
style="mso-tab-count: 1">      this(a, defaultB)
{}
   public Foo(string a,
string b) {
     
 /* do work here */
style="mso-spacerun: yes">   }
}


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l3 level1 lfo6; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Many languages automatically add a
public default constructor if you don’t specify any


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l3 level2 lfo6; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Abstract classes get a protected
constructor


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l3 level1 lfo6; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">These two code snippets are
equivalent:


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">public class
Foo {


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">}


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">public class
Foo {


size=2> style="mso-spacerun: yes">   public Foo ()
{}


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">}


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l10 level1 lfo7; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Always explicitly add a default
constructor to avoid versioning issues


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l10 level2 lfo7; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Adding a new constructor removes the
default one, breaking clients


size=2>//
V1


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">public class
Foo {


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">}


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">Calling Code works:
Foo f = new Foo()


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'"> 


size=2>//
V2


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">public class
Foo {
  public Foo (int
value)


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">}


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">Calling code
breaks: Foo f = new Foo()


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="FONT-WEIGHT: bold; FONT-SIZE: 10pt; FONT-FAMILY: Arial">Method
Usage
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l6 level1 lfo8; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Use overloading only when the
overloads do semantically the same thing


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l6 level2 lfo8; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Incorrect
overload:


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">String.IndexOf(string
value) {}


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">String.IndexOf(char[]
anyOf) {}


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l0 level2 lfo9; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Correct
overload:


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">Convert.ToString(int
value) {}


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">Convert.ToString(double
value) {}


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l11 level1 lfo10; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Used to avoid
boxing


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l11 level2 lfo10; tab-stops: list 1.0in"> face="Lucida Console" size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-fareast-font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">       
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Write(object) works for any
type


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l11 level2 lfo10; tab-stops: list 1.0in"> face="Lucida Console" size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-fareast-font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">       
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">But specialization avoids
boxing


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l11 level2 lfo10; tab-stops: list 1.0in"> face="Lucida Console" size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: 'Lucida Console'; mso-fareast-font-family: 'Lucida Console'; mso-bidi-font-family: 'Lucida Console'"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">       
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Do only when completely special
casing


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">public
static void Write (bool value);
public static void Write (int
value);
public static void Write (double value);
public static void Write
(object value);


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l8 level1 lfo11; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Use appropriate default
values


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l8 level2 lfo11; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Simple method assumes default
state


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l8 level2 lfo11; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">More complex methods indicate
changes from the default state


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">MethodInfo
Type.GetMethod (string name);
style="mso-spacerun: yes">    //ignoreCase =
false


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">MethodInfo
Type.GetMethod (string name,
style="mso-spacerun: yes">    boolean
ignoreCase);


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l12 level1 lfo12; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Use a zeroed state for the default
value (such as: 0, 0.0, false, “”, style="FONT-STYLE: italic">etc.)


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l12 level1 lfo12; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Be consistent in the ordering and
naming of method parameters


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l12 level1 lfo12; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Only the method with the most
parameters should be virtual if needed


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">public class
Foo {
   private const
string defaultForA = “a default”;
style="mso-spacerun: yes">   private const int defaultForB =
42;
   public void
Bar(){
     
Bar(defaultForA, defaultForB);
style="mso-spacerun: yes">   }
style="mso-spacerun: yes">   public void Bar (string
a){
     
Bar(a, defaultForB);
  
}
   public
/*virtual*/ void Bar (string a, int b){
style="mso-spacerun: yes">      // core
implementation here
  
}
}


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l7 level1 lfo13; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Variable number of arguments
(e.g.
printf)


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l7 level2 lfo13; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma; mso-bidi-font-weight: bold"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Use style="FONT-WEIGHT: bold">params


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">public
static string Format(string format,


size=2> style="mso-spacerun: yes">     params object[]
args);


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l4 level2 lfo14; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Not used for in/out params ( style="FONT-STYLE: italic">e.g. scanf)


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l4 level2 lfo14; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Only provide overloads for
performance reasons IF you special case each code
path


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'"> 


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">void Format
(string formatString, object arg1)


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">void Format
(string formatString, object arg1, object arg2)


size=2> style="FONT-SIZE: 10pt; mso-bidi-font-family: 'Courier New'">void Format
(string formatString, params object [] args)


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"> 


style="MARGIN: 0in 0in 0pt 0.5in; TEXT-INDENT: -0.25in; mso-list: l1 level1 lfo15; tab-stops: list .5in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Allowing method inlining by the
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">JIT face=Arial size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l1 level2 lfo15; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Minimize the use of virtual
methods


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l1 level2 lfo15; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Don’t write really large
methods


style="MARGIN: 0in 0in 0pt 1in; TEXT-INDENT: -0.25in; mso-list: l1 level2 lfo15; tab-stops: list 1.0in"> face=Tahoma size=2> style="FONT-SIZE: 10pt; FONT-FAMILY: Tahoma; mso-fareast-font-family: Tahoma"> style="mso-list: Ignore">• style="FONT: 7pt 'Times New Roman'">        
style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">Don’t have large numbers of
locals


style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">


More to come…

Comments (10)

  1. > Attributes: Never use overloaded constructors
    What’s the reason/idea behind this?

    Roland

  2. Frans Bouma says:

    – "Late in the final milestone we added a method to tell if the runtime is being shut down. However we added the method as an instance method making it completely uncallable"
    I might get the wrong idea reading this, but… is this method ever tested? I mean, the developer who hammered in that code, did he/she ever run the method? I don’t think so, because how would that be possible? Weird…

    – Does ‘sealing’ of classes get you any performance gains when using it on classes with solely static methods?

    – "Always explicitly add a default constructor to avoid versioning issues". This text is also in the library design guidelines in the .NET reference manual, and I first interpreted incorrectly: I thought I should add a default constructor ALWAYS, even if I already had a constructor in place which accepted parameters. Of course that’s not necessary.

  3. In the static classes section, it would be useful to mention the VB.NET Module type. Modules automatically gives you the behavior of a static class, except that it has no constructor, not even a private one, which I’d argue is even better.

    >Use a zeroed state for the default value (such as: 0, 0.0, false, “”, etc.)

    Isn’t the zeroed state for a string null, not ""?

  4. Frank Hileman says:

    Also, to allow better inlining, don’t inherit from MarshalByRef, or any of its derived classes: Component, Control, etc. Also Component is heavier than some people realize, and has a finalizer which may never be needed.

  5. Ram Prasad says:

    Does the usage of "Sealed" keyword in a virtual method will allow "JIT inlining"?