Best practices: throwing exceptions from properties

C#.NetExceptionProperties

C# Problem Overview


When is it appropriate to throw an exception from within a property getter or setter? When is it not appropriate? Why? Links to external documents on the subject would be helpful... Google turned up surprisingly little.

C# Solutions


Solution 1 - C#

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.

Solution 2 - C#

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.

Solution 3 - C#

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.

Solution 4 - C#

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.

Solution 5 - C#

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).

Solution 6 - C#

MSDN: Catching and Throwing Standard Exception Types

http://msdn.microsoft.com/en-us/library/ms229007.aspx

Solution 7 - C#

This is a very complex question and answer depends on how your object is used. As a rule of thumb, property getters and setters that are "late binding" should not throw exceptions, while properties with exclusively "early binding" should throw exceptions when the need arises. BTW, Microsoft's code analysis tool is defining the use of properties too narrowly in my opinion.

"late binding" means that properties are found through reflection. For example the Serializeable" attribute is used to serialize/deserialize an object via its properties. Throwing an exception during in this kind of situation breaks things in a catastrophic way and is not a good way of using exceptions to make more robust code.

"early binding" means that a property use is bound in the code by the compiler. For example when some code that you write references a property getter. In this case it is OK to throw exceptions when they make sense.

An object with internal attributes has a state determined by the values of those attributes. Properties expressing attributes that are aware and sensitive to the object's internal state should not be used for late binding. For example, lets say you have an object that must be opened, accessed, then closed. In this case accessing the properties without calling open first should result in an exception. Suppose, in this case, that we do not throw an exception and we allow the code access to a value without throwing an exception? The code will seem happy even though it got a value from a getter that is non-sense. Now we have put the code that called the getter in a bad situation since it must know how to check the value to see if it is non-sense. This means that the code must make assumptions about the value that it got from the property getter in order to validate it. This is how bad code gets written.

Solution 8 - C#

I had this code where I was unsure of which exception to throw.

public Person
{
    public string Name { get; set; }
    public boolean HasPets { get; set; }
}

public void Foo(Person person)
{
    if (person.Name == null) {
        throw new Exception("Name of person is null.");
        // I was unsure of which exception to throw here.
    }

    Console.WriteLine("Name is: " + person.Name);
}

I prevented the model from having the property being null in the first place by forcing it as an argument in the constructor.

public Person
{
    public Person(string name)
    {
        if (name == null) {
            throw new ArgumentNullException(nameof(name));
        }
        Name = name;
    }

    public string Name { get; private set; }
    public boolean HasPets { get; set; }
}

public void Foo(Person person)
{
    Console.WriteLine("Name is: " + person.Name);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJon SeigelView Question on Stackoverflow
Solution 1 - C#LBushkinView Answer on Stackoverflow
Solution 2 - C#Pavel MinaevView Answer on Stackoverflow
Solution 3 - C#Eric LippertView Answer on Stackoverflow
Solution 4 - C#JonnyRaaView Answer on Stackoverflow
Solution 5 - C#DavidView Answer on Stackoverflow
Solution 6 - C#smack0007View Answer on Stackoverflow
Solution 7 - C#Jack D MenendezView Answer on Stackoverflow
Solution 8 - C#FredView Answer on Stackoverflow