Tuesday, April 21, 2009

Can constructors throw exceptions?

In C# the answer is yes and is also part of the “Constructor Design Guidelines” on MSDN.

Do throw exceptions from instance constructors if appropriate.

The finalizer will be called on an object even if an exception occurred during its construction in C#.

In C++, it is important to remember that if an exception occurs in a constructor then, its destructor will not be called and you need to write the code to clean up memory in case an exception is raised in your constructor.

But the bottom line is this: because a constructor does not return a value – you need to typically use an exception to signal that the object was not created. And then depending on your language, handle the clean up appropriately. (The alternative is to use a zombie flag, that is set in case of an error in the constructor, which is then checked before any properties, methods are accessed).

Other guidelines from the document (C# constructor design guidelines):

  1. Consider providing simple, ideally default, constructors. A simple constructor has a very small number of parameters, and all parameters are primitive types or enumerations.
  2. Consider using a static factory method instead of a constructor if the semantics of the desired operation do not map directly to the construction of a new instance, or if following the constructor design guidelines feels unnatural.
  3. Do use constructor parameters as shortcuts for setting main properties.
  4. Do use the same name for constructor parameters and a property, if the constructor parameters are used to simply set the property. The only difference between such parameters and the properties should be casing.
  5. Do minimal work in the constructor. Constructors should not do much work other than to capture the constructor parameters. The cost of any other processing should be delayed until required.
  6. Do throw exceptions from instance constructors if appropriate.
  7. Do explicitly declare the public default constructor in classes, if such a constructor is required.
  8. Avoid having default constructors on structures.
  9. Do not call virtual members on an object inside its constructors.

No comments: