views:

207

answers:

3

The first thing I do in a public method is to validate every single parameter before they get any chance to get used, passed around or referenced, and then throw an exception if any of them violate the contract. I've found this to be a very good practice as it lets you catch the offender the moment the infraction is committed but then, quite often I write a very simple getter/indexer such as this:

private List<Item> m_items = ...;

public Item GetItemByIdx( int idx )
{
    if( (idx < 0) || (idx >= m_items.Count) )
    {
        throw new ArgumentOutOfRangeException( "idx", "Invalid index" );
    }

    return m_items[ idx ];
}

In this case the index parameter directly relates to the indexes in the list, and I know for a fact (e.g. documentation) that the list itself will do exactly the same and will throw the same exception. Should I remove this verification or I better leave it alone?

I wanted to know what you guys think, as I'm now in the middle of refactoring a big project and I've found many cases like the above.

Thanks in advance.

+1  A: 

It's true that possibly you duplicated work that's already been done in the API, but it's there now. If your error handling framework works and is solid, and isn't causing performance issues (profiling IYF) then I reckon leave it, and gradually phase it out if you have time. It doesn't sound like a top priority!

Robert Grant
+3  A: 

I would only do parameter verification where it would lead to some improvement in code behavior. Since you know, in this case, that the check will be performed by the List itself, then your own check is redundant and provides no extra value, so I wouldn't bother.

GWLlosa
+6  A: 

It's not just a matter of taste, consider

if (!File.Exists(fileName)) throw new ArgumentException("...");            
var s = File.OpenText(fileName);

This looks similar to your example but there are several reasons (concurrency, access rights) why the OpenText() method could still fail, even with a FileNotFound error. So the Exists-check is just giving a false feeling of security and control.

It is a mind-set thing, when you are writing the GetItemByIdx method it probably looks quite sensible. But if you look around in a random piece of code there are usually lots of assumptions you could check before proceeding. It's just not practical to check them all, over and over. We have to be selective.

So in a simple pass-along method like GetItemByIdx I would argue against redundant checks. But as soon as the function adds more functionality or if there is a very explicit specification that says something about idx that argument turns around.

As a rule of thumb an exception should be thrown when a well defined condition is broken and that condition is relevant at the current level. If the condition belongs to a lower level, then let that level handle it.

Henk Holterman
One other reason that the file open operation could fail is that the file does not exist. Although the risk is low, another user or process could have deleted it, adding to the pointlessness of the check. I agree that the test is pointless and giving a false sense of security. Better to try/catch.
BlackWasp
...that is, deleted the file between checking it exists and opening it.
BlackWasp
That's one of the things I meant with concurrency.
Henk Holterman