In the example code below I am taking a list of strings and concatenating them to a delimited string. The problem occurs when I use the setter with an empty list. The ToString method throws an ArgumentOutOfRangeException since the second parameter is a -1.
How should conditions (exceptions thrown in getters/setters) like this be handled?
I don’t like the fact that the setter throws an exception since the caller doesn’t know about the internals of the class and therefor should not have to handle (or even know how) the exception. Catching all exceptions in the getter/setter and quietly handling them also sounds like a bad idea since the caller will not know the getter/setter failed.
//I realize that this isn't the best code but I wanted to produce an example
//to demonstrate my question.
private string theStringVariable;
const string DELIMITER = ",";
public IList<string> StringList
{
set
{
StringBuilder stringBuilder = new StringBuilder();
foreach(string entry in value)
{
stringBuilder.Append(entry);
stringBuilder.Append(DELIMITER);
}
theStringVariable = stringBuilder.ToString(0, stringBuilder.Length - 1);
}
}
You should check for the potential, common error conditions, and throw your own exception (prior to the StringBuilder errors) right up front, with a meaningful error message.
In your case, you’ll most likely want to use some form of ArgumentException if the setter is called with an Empty string list. The key here is that your exception can say “the argument contained an empty collection” instead of “index out of bounds”, which is going to make the caller understand, immediately, why they have a “real” problem in their call.
On a side note: In cases like the code you posted – I’d also consider making this a method instead of a property. You’re doing quite a bit of “work” in this property setter, which is going to be somewhat unexpected. By making this a method, you’ll be giving the user a clue that there’s a bit of “processing” occurring within this property…