Exception in the constructor - a NO-NO !


Consider the following code:


* Note: this code was written for teaching purpose only and is highly not recommended in “real world” implementation.


public class CustomWriter : IDisposable
{
   private StreamWriter m_sw;

   public CustomWriter(string filePath, int numberOfLinesToWrite)
   {
      m_sw = new StreamWriter(filePath);

      if (numberOfLinesToWrite < 0)
      {
         throw new ArgumentException(“What’s wrong with you ?!!? numberOfLinesToWrite can’t be less than 0”, “numberOfLinesToWrite”);
      }

      // Assume that I’m using numberOfLinesToWrite here…
   }

   #region IDisposable Members

   public void Dispose()
   {
      // Time to say goodbye
      m_sw.Close();
   }

   #endregion
}


And now, here is a simple runner:


using (CustomWriter cw = new CustomWriter(@”c:\oren.txt”, 15))
{
   // some code here…
}


This one works as expected and the StreamWriter is being cleaned as using calls the Dispose method.

But what happens if the path is invalid like “c:oren.txt” or maybe “c:\windows\system32\cdosys.dll” ??
Nothing much to tell the truth as the resource(StreamWriter) will die and fail to initalize – we’re OK.


But what about this scenario:


using (CustomWriter cw = new CustomWriter(@”c:\oren.txt”, -5)) // <– Remember? “-5” is invalid argument
{
   // some code here…
}


Now we’re in trouble: The Dispose method is NOT called at all and the resource is running free on the memory street with no GC(garbage collector) police to hold him back (a little metaphor, why not?). Need I to say how BAD this case is ?!


 


To sum it all up: constructors should NEVER throw any kind of exception. If you have a case which you need to do some extra initialization that could throw an exception in certain cases – do it in a method inside the class (Initialize() sounds right).


* I’d like to give the deserved credit for Amir Engel(His blog is on its way, hold tight) for elaborating on the subject with me ;-)