What exception to throw from a property setter?

Have a look through mscorlib.dll with Reflector, in a similar situation such as System.String.StringBuilder.Capacity Microsoft use ArgumentOutOfRangeException() similar to:

public int PropertyA
{
    get
    {
        return //etc...
    }
    set
    {
        if (condition == true)
        {
            throw new ArgumentOutOfRangeException("value", "/* etc... */");
        }
        // ... etc
    }
}

To me ArgumentException (or a child) makes more sense, because the argument (value) you provided is not valid, and this is what ArgumentException was created for.


I wouldn't throw an exception at all. Rather I would allow a string of any length and then have a seperate "Validate" method on the class that is called before saving. There are a number of scenarios particularly if you use databinding where throwing exceptions from property setters can get you in a mess.

The trouble with throwing exceptions from property setters is that programmers forget to catch them. It kind of depends upon how clean you expect the data you are getting to be. In this case I would expect long string lengths to be common not exceptional and as such using an exception would be "flow control with exceptions".

To quote from the Microsoft's Design Guidelines for Developing Class Libraries:

Do not use exceptions for normal flow of control, if possible. Except for system failures and operations with potential race conditions, framework designers should design APIs so that users can write code that does not throw exceptions. For example, you can provide a way to check preconditions before calling a member so that users can write code that does not throw exceptions.


Remember how many problems in computer science are solved by adding an extra level of indirection?

One approach would be to create a new type, FixedLengthString, say. It would be instances of that type that validate lengths of strings they are initialised with - with a conversion operator to do type conversion from a plain string. If your property setter takes such a type as its argument then any violation would become a type conversion exception instead of an argument/ property exception.

In practice I would rarely do this. It smells a bit of taking OO too far - but in some cases it can be a useful technique, so I mention it here for completeness.


public IPAddress Address
{
    get
    {
        return address;
    }
    set
    {
        if(value == null)
        {
            throw new ArgumentNullException("value");
        }
        address = value;
    }
}

via MSDN