Had a hunch. I have yet to stumble across one of these
VB glitches (proper usage of the term "glitch" by the way), like the behavior of IIf, that C# doesn't resolve sensibly.
The problem is with the
VB compiler. When
VB compiles a call to IIf, it has to evaluate all three parts of the IIf (the condition, the true part and the false part) and then send them to the IIf function for further evaluation. Here's a couple of other weird situations from the .NET blog that this could give rise to (IIf in
VB.NET has the same problems, 'cause its actually still the
VB IIf from the Microsoft.VisualBasic namspace):
Dim info As String
info = IIf(foo Is Nothing, GetDefaults(), GetObjInfo(foo))
In
VB/
VB.Net, both functions GetDefaults() and GetObjInfo(foo) get called!
or this one:
Dim info As String = IIf(foo Is Nothing, "EMPTY", foo.data)
Before even calling IIf, the
VB.NET compiler emits IL to:
- Evaluate the "foo is Nothing" conditional
- Load the string "EMPTY"
- Load the value of foo.data (but how can you load the value of foo.data
if foo is null?). You get a NullReferenceException.
Here's how C# resolves the problem. The C# conditional operator (indicated by a '?') test for division by zero correctly. If x doesn't equal 0, the division occurs, else 1 is returned. When the C# compiler encounters the conditional operator, it emits IL very similar to an if/then/else statement (which is really the preferred method for handling this test in
VB too).
// cs_divisionby0_test.cs
using System;
class Test
{
public static double sinc(double x)
{
return x != 0.0 ? Math.Sin(x)/x : 1.0;
}
public static void Main()
{
Console.WriteLine(sinc(0.2));
Console.WriteLine(sinc(0.1));
Console.WriteLine(sinc(0.0));
}
}
Output
0.993346653975306
0.998334166468282
1
No wonder Microsoft has stated that it intends to support VBA for one more release of Office. I still have no idea why IIf isn't blowing up in the SQL case.
Bob