Archive for December 2005

Things I Learned Today

In VB.NET, a string with a value of Nothing is treated as equivalent to “”. Thus,

dim myString as String = Nothingif myString = "" then Debug.Print "myString is blank"

will in fact print “myString is blank”. On the surface, this seems fairly helpful because it can eliminate exceptions when comparing myString (Nothing) to an empty string. And, you can still detect if it is Nothing. So what’s the problem?

Well, in Property setters, a common pattern goes like this:

public property MyString as String Get     ... End Get Set (Value as String)        if _myString  Value then          _myString = Value         RaiseEvent MyStringChanged(Me, Nothing)     end if End SetEnd property

(this pattern is useful to achieve proper 2-way objectcontrol data binding)

The problem becomes that when you set a property this way, and the new value = “”, then _myString never gets set. And the string variable stays as Nothing, i.e. uninitialized. Annoying, and in my case a source of a bug. Which leads me to….

The other thing I learned today was that WinForms Data Binding eats errors. That is, when an error occurs inside of the Microsoft binding code, it is not propogated; it simply disappears. You can see that exceptions have occurred by watching the .NET Exceptions counter in Windows Performance Monitor, or the .NET tab on a process in SysInternals Process Explorer.

In my case, the symptom was that when tabbing through controls, the tab would not leave the control with the error. Clicking on the next control would also not work, although clicking elsewhere on the app worked ok.

The cause was an error in either of the bound properties, i.e. the Control.Text property, or the object property that I was binding to. If the Property Set of either of these gives an error, then the above-mentioned symptom occurs. My particular problem was that I do not expect my object properties to ever be set to Nothing, so my control could give an error when that happened (Control.Text = Nothing).

Some error handling advice

A fairly well-known philosophy of coding is to “fail early”. What this
means is that you should code for errors according to your own expectations.
If you expect an error to occur, then trap and respond to that specific
error, and let other errors go by. (This is not to say that you should let
the program crash – just that you shouldn’t handle the error prematurely).

Thus, the code will initially fail more often with errors, but you will find
out about them sooner rather than later. Quality improves because you will
find more errors in a test environment, before the code is deployed to a
site. (The same reason we do continuous builds – it is cheaper to fix
problems earlier than it is later).

This is why, in VB6 “On Error Resume Next” is bad, and in .NET “Catch ex as
Exception” is equally poor. If you see “On Error Resume Next” in VB6 code,
it generally means you have discovered some poor quality code. It is not
easy to fix, because removing the error handling statements will lower the
quality in the short-term, (but raise it in the long-term).

In .NET and Java, you can be even more pro-active, by validating arguments.
For example, if I have a method that expects a parameter to be present, I
can throw an exception (raise an error) right at the start of the method
when it receives a NULL value. Then, my method will fail early
(ArgumentNullException), rather than later in the call stack
(NullReferenceException/Object Variable Not Set) where the reason is less
obvious.