Tuesday, December 16, 2008

VB.Net and Optional Parameters - watch out!

I read somewhere recently that C# 4.0 will also have optional parameters, like VB6 and VB.Net had all along.
When moving to .Net I decided not to use optional parameters in VB.net since they were kind of looked at as a remnant of VB6, not CLR compliant, not available in C# etc.

And the "preferred way" was to use overloads instead of Optional Parameters.

So now after I read that C# 4.0 will have optional parameters (and the fact that I am kind of "over" the many overloads that are sometimes necessary, especially if you have logging methods etc.) I was thinking of going back to using Optional Parameters.

I always assumed that the compiler for VB.Net would just created the overloads in the background, substituting it with the default values given to the Optional Parameters.

But that is not the case. The compile hard-compiles the default values into the CALLING method/object and not as an overload into the called method.

Joel On Software

VB.NET Optional parameters

Optional Parameters (VB.NET)

Now this was a big red flag for me, because that means each time you change the value of one of the default parameters, you would need to recompile ALL the CALLING classes as well (if they call with some of the optional parameters omitted).

So if you have a live enterprise system with multiple DLLs and you need to deploy hotfixes as individual DLLs then you'd have to deploy the changed DLL and all the DLLs that call it. Otherwise the "old" DLLs will still call your method with the "old" default value and this could introduce some hard-to-find side effects.

One might argue how often do you really need to change the default value of an Optional Parameter and that that indicates a deeper design issue.
But still, for complex system or legacy code that you are refactoring this might be a real possibility.

Furthermore in VB.Net 3.5 you cannot use Nullable types as optional parameters, i.e. you cannot do this:

Public Sub DoStuff(Optional ByVal intEntityID As Nullable(Of Integer) = Nothing)

End Sub

So my conclusion at this point is to stick with overloads instead of Optional Parameters. More predictable and less things to remember as possible pitfalls. :)
I got enough other stuff to cram into my head ...