Creating a property that can raise an IndexOutOfRangeException

I have a class containing a set of elements. For convenience, I provided GetCurrentItem, which is implemented

public Type GetCurrentItem { get { return this.items[this.items.Count - 1]; } } 

which throws an exception if there are no items in the list.

Should I give an exception or should I return null ? If it was the API that I passed you, what would you expect? Exception or null? Is there a better way to handle this?

+7
source share
7 answers

What is relatively more true? As Kirk says, it depends. Sometimes a null makes logical sense, and sometimes an exception is better suited if the default is not reasonable. One thing I'm trying to do is think that β€œis GetCurrentItem causing a logical failure or a safe thing?”

If this is not a GetCurrentItem call when it is not, then throwing an exception is the right course. For example, if your collection has the HasCurrent or IsEmpty property, where someone can check the result before calling GetCurrentItem , then they should "know better." But if the current null element is the right logical way to use your class, then by all means its design. In any case, I would document the behavior in the code comments so that users are aware of the expected behavior.

I will say this, however, by throwing an ArgumentOutOfRange exception, there may be bleeding implementation details. That is, if the user of this class does not know that the internal structure is an array or List<T> , then do not deflate this exception, but understand it, wrap it and throw a more significant one (user-defined or something like InvalidOperationException ).

Since they really don't pass the argument directly, they get an ArgumentOutOfRange exception, which can be confusing :-)

+9
source

Let this raise an error. This is exactly how other collections work. This should be before the user application to handle potential exceptions (especially when working with collections). Maybe there should be a bool HasSelection() method that the user can call before continuing.

+3
source

Exceptions should be used for exceptional cases. If CurrentItem can be null, you should not throw an exception. I do not understand why not having CurrentItem is exceptional.

+3
source

The question is, do you expect GetCurrentItem to return a safe value. If the Type is null, then GetCurrentItem should probably return null when the current element is missing. If you always expect the list to be nonempty and something will always be selected by default, then throw a meaningful exception.

As a rule, you should not throw an exception if your business is really an exception and not a normal use case. However, this can be quite subjective.

+1
source

I am trying to think about it from a user perspective. Go for the Principle of Least Amazement .

If I used a library or object and raised GetCurrentItem and IndexOutOfRangeException was thrown, I would have thought: "I have not called anything with an index, I need the current element." So my suggestion would be to return null, which would make me think: "Oh, there is no current element."

Alternatively, if the property was an index, and I wanted to get an element with a specific index, I would not be surprised at IndexOutOfRangeException .

+1
source

If this GetCurrentItem makes sense for your API, I would throw an "InvalidOperationException" when there are no elements. You can call it another way if you allow null as a valid result.

Consider if the existing LINQ Last method already provides the same functionality.

0
source

If in doubt, follow .NET. This function is similar to List.Last (), which throws an exception if it is empty.

http://msdn.microsoft.com/en-us/library/bb358775

0
source