Here is a pop quiz for language aficionados.
Examine the following class:
public
class Foo
{
public
int GetUpperLimit()
{
Console.WriteLine("GetUpperLimit
invoked");
return
5;
}
public
IEnumerable<int> GetCollection()
{
Console.WriteLine("GetCollection
invoked");
return
new
int[] { 1, 2, 3, 4, 5 };
}
}
Now examine the following console mode program:
class
Program
{
static
void Main(string[] args)
{
Foo
foo = new
Foo();
for
(int i = 1; i <=
foo.GetUpperLimit(); i++)
{
Console.WriteLine(i);
}
foreach (int
i in foo.GetCollection())
{
Console.WriteLine(i);
}
}
}
Without using a compiler, do you know:
- How many times "GetUpperLimit invoked" will appear in the output?
- How many times "GetCollection invoked" will appear in the output?
Now, examine the same console program in VB:
Sub Main()
Dim
foo As
New Foo()
For
i As
Integer = 1 To foo.GetUpperLimit()
Console.WriteLine(i)
Next
For Each
i As
Integer In foo.GetCollection()
Console.WriteLine(i)
Next
End Sub
Bonus third question:
- Will the output of the VB program be the same as the C# program?
I was suprised by the answer to the last question ...
Comments
Ok, quick guess, I'd say 5 GetUpperLimits, and 1 GetCollection.
For the VB, 1 GetUpperLimit and 1 GetCollection.
I'm sure I read an article about when the foreach loop would take the initialization outside the loop, but I can't remember what the rules were!
The most obvious answer would be 5 for everything, but I'm sure you wouldn't ask if that were true... would you :)
I've also got thoughts like debug vs optimized running round my head, but I suppose changing the behaviour would be a bit severe!
Oops, the C# code was bungled, sorry about that.
The answer of 5 for the GetUpperLimit is close...
It is called at the very start after 'i' is initialised to 1, then again after 'i' has been incremented to 2, 3, 4, 5 respectively then finally after it is incremented to 6?
6 for the getUpperLimit - the last one being from the failing condition test!
I'm smiling now, with a warm fuzzy feeling... I REALLY should get out more :)))
C# - 5 for the loop and 1 for the failing test.
VB - The function is evaluated outside the loop and cached. So the routine is only called once.
In the VB world, that's why you can get better performance in a "For x = 1 to recordset.count" vs. "do until recordset.EOF"
Both languages are holding on to thier heritage (C++ for C#, VB for VB.NET). Overall, it's still about the runtime and the class library, so there generally isn't a huge difference in selecting one of these programming languages.
Last, but not least, I want to thank you for keeping this blog: I may not be the most qualified guy to tell this, but I think your blog is one the the five most interesting to read.