|
|
VB.NET Optional ParamatersAnd Why to Avoid Them | | A little while back, I was reading an article in C SharpPro magazine which was a list of tips for VB.NET programmers who are learning C#. The author has a pretty strong opinion on Optional Parameters and why they should be avoided. The case he makes is pretty straightforward, namely, that C# doesn't support optional parameters and forces you to use overloading. While it may take more work to write multiple overloads, his contention is that it's a good thing because when the compiler implements optional parameters, it's actually writing the overloaded functions for you. Accordingly, he feels that the main reason to avoid Optional parameters is that they allow you to do things you don't understand, and therefore keep you away from your code. I think there's some merit in this argument, but one could easily counter with something like this: "I use optional parameters and they save me lots of time. I could write each overload individually but that would take much more time. I didn't know that this is a 'shortcut' and that the CLR actually turns them into overloaded methods, but I do know. And from now on, each time I use an optional parameter, I'll pause, mentally envision how long it would take to write each overload, then get back to coding. Now that I know fully what my overloaded code would look like, I'm just as well off as if I had actually coded the multiple overloads, but I'm way ahead one time. Shortcuts, provided they have no adverse side effects that the long way doesn't and aren't cutting corners, are a good thing. Optional Parameters don't cost anything more than multiple overloads but save time, ergo, they are a good thing." (And since the argument is phrased in terms of a Proof, even elitist professors should admire it). Well, if every premise of this argument were true, then I would agree with it. Why write 50 lines of code when 3 would suffice if I gain nothing but writing the 50 lines? Aftera all, isn't the whole .NET paradigm "Do More With Less"? However, all of the premises aren't entirely true.
When I first read the article, I fired up VS 2003, created a VB.NET project and coded a method titled OptionalCall , compiled it, went to the VS.NET command prompt, fired up ILDASM.exe and pointed it to my assembly. When I looked at the IL, here's what I saw:
.method public instance void OptionalCall(string s,
[opt] string myOptional) cil managed
{
.param [2] = "Optional"
// Code size 16 (0x10)
.maxstack 8
IL_0000: nop
IL_0001: ldarg.1
IL_0002: ldarg.2
IL_0003: callvirt instance string [mscorlib]System.String::ToString()
IL_0008: call valuetype [System.Windows.Forms]System.Windows.Forms.DialogResult [System.Windows.Forms]System.Windows.Forms.MessageBox::Show(string,
string)
IL_000d: pop
IL_000e: nop
IL_000f: ret
} // end of method Form1::OptionalCall |
I highlighted the [opt] instruction to show that it indicates an optional argument. And as far as the code goes, this is it. There aren't any other functions, so I started to wonder if he was correct. Since then, I've asked around on a few MS Newsgroups and at first, most people came to the same conclusion I first did..namely, that the author was incorrect. However, I have it on good authority that although the IL is the same, the physical implementation is the same as overloads b/c the [opt] instruction causes the CLR to effectively create the overloads. At this time, I believe the author is correct, but I can't get anyone in the know to go on record on this issue.... So, if we can't establish that this is a downside, and optional params clearly provide some benefit, should we accept them as a good methodology? I would still argue no. If the author is correct, it will only reinforce my argument, but either way, I think a good argument can be made against them. Allow to explain why:
Problem #1 - No Cross Langauge Support
I've ranted and raved for months now that the VB.NET vs. C# argument is too silly to waste time discussing. Professional programmers should be willing to learn whatever tool it takes to get the job done, and learning to think in other languages not only makes you more marketable, it gives you the ability to communicate with people with different backgrounds. I've also said that you should focus on learning the .NET Framework because that's the 'hard' part. Trust me on this, true Professionals like Jeffrey got to be where they are by keeping an open mind and learning everything they can. And while I haven't asked him personally, I think it's a safe bet that he learned .NET first using C#, then learned VB.NET in a very short time. I'll bet it took most top notch VB6/VC++ programmers a lot longer to learn .NET than it did for Jeff to learn the other language. With that said, Optional Parameters throw a monkey wrench into this. Using them reduces cross language translastions and since most C/C++/Java programmers wouldn't know what an optional parameter was (or want to know) if it bought them a beer, it would cause some confusion. Sure, I bet most of them could figure it out in a few seconds, but that doesn't negate my point. Moreoever, there will never be IL written in C# (at least under the current specs) that will emit the [opt] instruction as used in this context. So even for the ultra 'real' programmers who read/write IL, this could throw them for a curve. And trust me on this, even if most C# programmers see the [opt] instruction or the optional keyword, unless they have some VB experience, their first conclusion will be to view it as a mandatory parameter.
Problem #2 - They Impede flexibilty and can introduce logic errors
I've been flamed up and down for this position, but I stand firmly by it. Let's say that I create a Class Library in VB.NET (after all, you should be able to use my library with any .NET language, and what I wrote it in is of little concern) and I have an optional parameter as my second argument which defaults to 0.06 [Let's say the we have a Point of Sale app and this function computes the sales tax on a given purchase..you pass in the amount of purchase and we have an optional Parameter for sales tax]. As such, tax rates tend to fluctuate (usually upward unfortunately) so a change is made in the next version of the .dll which moves the rate to .08. However, none of our customers are affected by the tax rate (maybe I sell to a partially exempt organization) so for out purposes, the effective rate is still .06 . Or, say we wrote out app so that we would manually update every increase and not wait on the .dll. However, all of our logic is based on .06. What happens when we install the update? All of our code now needs revised. Hopefully we knew about it before it was implemented, but as is often the case, version upgrades have many new features/changes, and one or two can slip through the cracks no matter how careful you are. If I made you pass in the rate in the first place, and you used a constant for your tax rate, one line of code would be all it took to update the tax rate.... I've been told this never happens in the real world, but only by VB.NET programmers who get touchy about Optional Parameters.
Problem #3 - Limit the ability to Implement Coding Standards
This is an adjunct to the first argument, but it is nonetheless valid. Many times programming departments, try to standardize coding, documentation and testing. If you have a programmer that uses Optionals, no one will be able to write in any other language without breaking the standards. Moreover, you may have a base class that originally uses no parameters. Then, you have multiple derived classes based on this class. So as far as all of the base classes are concerned, method X takes no parameters. Now, if you added an Optional Parameter to the base class, you may introduce some problems. Why? Because let's say that the base class no has an optional String Parameter. The derived classes may have implemented their own version of the same method, but with a String argument. Now you'll have some problems with collision....This never happens either according to the aforementioned crowd.
Now, I want to emphasize that I'm in no way disparaging VB.NET or VB Programmers. I'm one myself and I love VB.NET. I do think that C# is unencumbered by some of the legacy issues that plague VB.NET but there's a very easy way to immunize your code from this....don't depend on those shortcuts!
Conclusion:
I think that overall, the costs of using Optional Parameters outweigh the benefits. However, that really depends on a lot of factors. And they are a legitimate shortcut and time saver. My point is simply to raise some awareness of some of the problems associated with their use.
|
|