How to bulletproof the loops?

Here is one example about how to bulletproof the loops. This example holds well for legacy code and – of course – for hurry-written-code (that might be the current one, unfortunately).

One of the most dangerous things I’ve seen are pieces of code that loop through object arrays and lists, same time expecting that array or list contains only correct elements. What do you think about ArrayList by example? Is it able to hold only those objects that are correct ones in current context or is ArrayList more powerful and can hold also incorrect objects?

Well, I’m always very suspicious when I see ArrayList or IList on .Net 2.0 code. I always ask myself one question: isn’t it possible to refactor this code so there is List<ImportantClass> instead of ArrayList or IList? If it is possible then I will refactor this code.

Here’s my example.


public void SaveChanges(ArrayList entries)
{
   
foreach (MyObject bizObject in
entries)
    {
       
if (bizObject.IsDirty)
            bizObject.Save();
    }
}

What bad things may happen?

  1. Entries may be null.
  2. It is possible that entries list contains nulls.
  3. It is possible that entries list contains entries that are impossible to cast to required type.
  4. On large arrays cast has some impact on performance.

One can argue now that it is possible to use try-catch here and suppress all the errors. No problem – you can do it – if you want to see some grey hair (color code: #EFEFEF) in mirror after couple of debugging sessions. Try-catch overuse has these bad side efects.

  1. It may suppress also these exceptions that are thrown out by IsDirty property or Save method.
  2. When exception is thrown then try-catch needs hell load of resources in some cases.

So, what kind of code should be the best shot (in my humbe opinion)? I consider something like this. Instead of List<MyObject> you can use the generic list or collections that fits your needs better.


public void SaveChanges(List<MyObject> entries)
{
   
if (entries == null
)
       
return
;

   
foreach (MyObject bizObject in
entries)
    {
       
if (bizObject == null
)
           
continue
;

       
if (bizObject.IsDirty)
            bizObject.Save();
    }
}

Of course, we can also add here exception handling if we need it but it has nothing to do with exceptions that can be easily avoided here. Also it is not possible anymore to add other objects that can cause cast exceptions to our list. And we will also win on performance because we are checking the objects instead of waiting for errors.

Happy looping, guys! 🙂


6 thoughts on “How to bulletproof the loops?

  • Good tips…specially for all the new beginners out there.

  • nixen says:

    I understand your issues with ArrayLists, but could you please elaborate what’s wrong with IList?

    Afaik, using IList over List basically tells the consumer of the code a thing or two about the intent of the value, doesn’t make it any more or less dangerous.

  • Gunnar says:

    IList is just an interface that lists implement. You can use also IList instead of ArrayList in this example.

  • steve says:

    whats wrong with this code?

    Looks pretty similar and works just the same no?

    public void SaveChanges(ArrayList entries)
    {
    if(entries == null)
    continue;

    foreach(MyObject bizObject in entries)
    {
    if(bizObject == null)
    continue;
    if(bizObject.IsDirty)
    bizObject.Save();
    }
    }

  • Gunnar says:

    ArrayList can contain all kinds of objects. If you have objects of class A in ArrayList nothing stops you adding objects of class B there. So, to be safe you should check the object type. Using generic list in this case guarantees that there is no objects of other types.

    If you are using value types then you lose in performance because of unboxing operations.

Leave a Reply

Your email address will not be published. Required fields are marked *