Nel suo sito OdeToCode, Scott Allen ha proposto un quiz interessantissimo di cui proporrò la versione VB.NET 2005 (l’originale qui è in C#, sempre 2005, con rimando al VB).
In poche parole, sia data una classe
Public Class Foo
Public ReadOnly Property GetUpperLimit() As Integer
Get
Console.WriteLine("GetUpperLimit invoked")
Return 5
End Get
End Property
Public ReadOnly Property GetCollection() As IEnumerable(Of Integer)
Get
Console.WriteLine("GetCollection invoked")
Dim result As New Collections.Generic.List(Of Integer)
result.Add(1)
result.Add(2)
result.Add(3)
result.Add(4)
result.Add(5)
Return result
End Get
End Property
End Class
Quindi sia dato un programma che la usa…
Module Module1 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 Console.ReadLine() End Sub End Module
Le domanda che Allen pone sono molto semplici: senza usare un compilatore sareste in grado di dire…
- Quante volte nell’output apparirà la stringa
"GetUpperLimit"? - Quante volte nell’output apparirà la stringa
"GetCollection"? - E soprattutto: l’output del programma VB sarà lo stesso dell’output del programma C#?
Se andrete al link originale vedrete il mio commento nel quale faccio un figurone… da cioccolataio.
Dal momento che io a quell’Allen lì non son degno neanche di allacciargli le scarpe, non lascerò il quesito senza soluzione:
C#
GetUpperLimit invoked 1 GetUpperLimit invoked 2 GetUpperLimit invoked 3 GetUpperLimit invoked 4 GetUpperLimit invoked 5 GetUpperLimit invoked GetCollection invoked 1 2 3 4 5
VisualBasic.NET
GetUpperLimit invoked 1 2 3 4 5 GetCollection invoked 1 2 3 4 5
Beh, a parte il mio orgoglio ferito, in realtà questo semplice esercizio ha posto in rilievo una cosa che avevo sempre ignorato: in VisualBasic.NET la GetUpper Limit viene valutata una sola volta prima del ciclo ed il suo risultato viene messo nella cache e riutilizzato ad ogni ciclo, migliorando le performance.