Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices: throwing exceptions from properties

People also ask

Should properties throw exceptions?

Property Get Methods Fields don't throw exceptions and neither should properties. If you have a property that throws an exception, consider making it a method. The following exceptions can be thrown from a property get method: System.

How do you handle throwing exceptions?

Using the Throws keyword Throws is a keyword used to indicate that this method could throw this type of exception. The caller has to handle the exception using a try-catch block or propagate the exception. We can throw either checked or unchecked exceptions.

Which of the following is most preferred way of throwing and handling exception?

Answer» b. throw by reference and catch by reference.


Microsoft has its recommendations on how to design properties at http://msdn.microsoft.com/en-us/library/ms229006.aspx

Essentially, they recommend that property getters be lightweight accessors that are always safe to call. They recommend redesigning getters to be methods if exceptions are something you need to throw. For setters they indicate that exceptions are an appropriate and acceptable error handling strategy.

For indexers, Microsoft indicates that it is acceptable for both getters and setters to throw exceptions. And in fact, many indexers in the .NET library do this. The most common exception being ArgumentOutOfRangeException.

There are some pretty good reasons why you don't want to throw exceptions in property getters:

  • Because properties "appear" to be fields, it is not always apparent that they can throw a (by-design) exception; whereas with methods, programmers are trained to expect and investigate whether exceptions are an expected consequence of invoking the method.
  • Getters are used by a lot of .NET infrastructure, like serializers and databinding (in WinForms and WPF for example) - dealing with exceptions in such contexts can rapidly become problematic.
  • Property getters are automatically evaluated by debuggers when you watch or inspect an object. An exception here can be confusing and slow down your debugging efforts. It's also undesirable to perform other expensive operations in properties (like accessing a database) for the same reasons.
  • Properties are often used in a chaining convention: obj.PropA.AnotherProp.YetAnother - with this kind of syntax it becomes problematic to decide where to inject exception catch statements.

As a side note, one should be aware that just because a property is not designed to throw an exception, that doesn't mean it won't; it could easily be calling code that does. Even the simple act of allocating a new object (like a string) could result in exceptions. You should always write your code defensively and expect exceptions from anything you invoke.


There's nothing wrong with throwing exceptions from setters. After all, what better way to indicate that the value is not valid for a given property?

For getters, it is generally frowned upon, and that can be explained pretty easily: a property getter, in general, reports the current state of an object; thus, the only case where it is reasonable for a getter to throw is when the state is invalid. But it is also generally considered to be a good idea to design your classes such that it is simply not possible to get an invalid object initially, or to put it into invalid state via normal means (i.e., always ensure full initialization in constructors, and try make methods exception-safe with respect to state validity and class invariants). So long as you stick to that rule, your property getters should never get into a situation where they have to report invalid state, and thus never throw.

There is one exception I know of, and it's actually a rather major one: any object implementing IDisposable. Dispose is specifically intended as a way to bring object into an invalid state, and there's even a special exception class, ObjectDisposedException, to be used in that case. It is perfectly normal to throw ObjectDisposedException from any class member, including property getters (and excluding Dispose itself), after the object has been disposed.


It is almost never appropriate on a getter, and sometimes appropriate on a setter.

The best resource for these sorts of questions is "Framework Design Guidelines" by Cwalina and Abrams; it's available as a bound book, and large portions of it are also available online.

From section 5.2: Property Design

AVOID throwing exceptions from property getters. Property getters should be simple operations and should not have preconditions. If a getter can throw an exception, it should probably be redesigned to be a method. Note that this rule does not apply to indexers, where we do expect exceptions as a result of validating the arguments.

Note that this guideline only applies to property getters. It is OK to throw an exception in a property setter.


One nice approach to Exceptions is to use them to document code for yourself and other developers as follows:

Exceptions should be for exceptional program states. This means it's fine to write them wherever you want!

One reason you might want to put them in getters is to document the API of a class - if the software throws an exception as soon as a programmer tries to use it wrong then they wont use it wrong! For instance if you have validation during a data reading process it may not make sense to be able to continue and access the results of the process if there were fatal errors in the data. In this case you may want to make getting the output throw if there were errors to ensure that another programmer checks for this condition.

They are a way of documenting the assumptions and boundaries of a subsystem/method/whatever. In the general case they should not be caught! This is also because they are never thrown if the system is working together in the way expected: If an exception happens it shows that the assumptions of a piece of code are not met - eg it is not interacting with the world around it in the way it was originally intended to. If you catch an exception that was written for this purpose it probably means the system has entered an unpredictable/inconsistent state - this may ultimately lead to a crash or corruption of data or similar which is likely to be much harder to detect/debug.

Exception messages are a very coarse way of reporting errors - they cannot be collected en-masse and only really contain a string. This makes them unsuitable for reporting problems in input data. In normal running the system itself should not enter an error state. As a result of this the messages in them should be designed for programmers and not for users - things that are wrong in input data can be discovered and relayed to users in more suitable (custom) formats.

The Exception (haha!) to this rule is things like IO where exceptions are not under your control and cannot be checked for in advance.


This is all documented in MSDN (as linked to in other answers) but here is a general rule of thumb...

In the setter, if your property should be validated above and beyond type. For example, a property called PhoneNumber should probably have regex validation and should throw an error if the format is not valid.

For getters, possibly when the value is null, but most likely that is something you will want to handle on the calling code (per the design guidelines).