Friday, August 05, 2005

Short-circuiting comparisons

This was one of those things that I read about and though 'Huh. When am I ever going to use that?' Turns out it's pretty useful at times.

VB.NET can short circuit comparisons using the AndAlso an OrElse keywords.

What's short-circuiting?
Short circuiting occurs when you have multiple comparisons on a line and the outcome is known before you get to the end of the line. Take the following line of code:
If 1=2 And 3=3 Then
'Do some stuff
End If


You know after the first part (1=2) that the comparison is going to return false, but the second part is still evaluated (i.e. the machine still checks to see if 3 does in fact equal 3). However, if you were to use this:
If 1=2 AndAlso 3=3 Then
'Do some stuff
End If


The machine skips the 3=3 part of the comparison. Just ignores it. It knows that since 1!=2 the result is going to be false, so it just skips over the second part.

So?
That contrived example doesn't look too useful. However, if we look at a real world example, all becomes clear:

Dim ds as Dataset = GetMyDataset()
Dim dr as DataRow = GetMyDataSet.Tables(0).Rows(0)
If Not IsDbNull(dr("FieldName")) And dr("FieldName") > 0 Then
'Do some stuff
End If


Because we're using the normal 'And', if the value in the row specified is null, the method will throw an exception because a value of type DBNull can't be cast to an integer. Although 'Not IsDbNull(dr("FieldName"))' returns false (because it is null) the second section is still evaluated. And because it's a null value, an exception is thrown.

However, if we use AndAlso, the comparison is short-circuited and it doesn't throw an exception:

Dim ds as Dataset = GetMyDataset()
Dim dr as DataRow = GetMyDataSet.Tables(0).Rows(0)
If Not IsDbNull(dr("FieldName")) AndAlso dr("FieldName") > 0 Then
'Do some stuff
End If


Because the first part of the comparison return false, the framework knows that the overall expression is going to return false, so it doesn't bother trying to evaluate the second part, and it doesn't throw an exception.

Needless to say, OrElse works in exactly the same way, but for Or's rather than And's.

It's come in handy for me a couple of times recently, anyway.

Just wanted to share.

No comments: