Mi sono accorto di un diverso comportamento tra C# e VB.NET, comportamento che mi ha gratificato ancora una volta nell'aver scelto C# al posto di VB.NET (Nota per i vbfanatici: preferire non vuol dire disprezzare).
I termini della questione:
Ho un ArrayList, lo popolo con 4 Array di char con i valori (a coppie: 1-3,2-4,3-6,4-7), poi con un ciclo "For/for" estraggo i dati e cancello un elemento.
C#
ArrayList ar = new ArrayList();
ar.Add(new char[] {'1','2'});
ar.Add(new char[] {'3','4'});
ar.Add(new char[] {'5','6'});
ar.Add(new char[] {'7','8'});
for (int i = 0; i < ar.Count; i++)
{
char[] c = (char[]) ar[i];
Console.WriteLine(string.Format("{0} {1} {2}",i,ar.Count,c[0]));
if (i == 1)
ar.RemoveAt(i);
}
VB.NET
Dim ar As New ArrayList()
ar.Add(New Char() {"1"C, "2"C})
ar.Add(New Char() {"3"C, "4"C})
ar.Add(New Char() {"5"C, "6"C})
ar.Add(New Char() {"7"C, "8"C})
For i As Integer = 0 To ar.Count - 1
Dim c() As Char = Ctype(ar(i),char())
Console.WriteLine(String.Format("{0} {1} {2}", i, ar.Count, c(0)))
If i = 1 Then
ar.RemoveAt(i)
End If
Next
Come si può vedere sono del tutto analoghi con una piccola / grande differenza: Il ciclo VB.NET genera un errore.
L'istruzione per la chiusura del ciclo for su C# viene valutato ad ogni esecuzione quindi quando ar.Count cambia C# ne tiene conto.
L'istruzione per la chiusura del ciclo For su VB.NET è valutata una sola volta all'inizio se ar.Count cambia VB.NET NON ne tiene conto.
Ne consegue che l'errore che esce solo su VB.NET con le istruzioni mostrate è più che plausibile (purtroppo).
Il workaround per VB.NET è NON usare il ciclo For e al suo posto un ciclo While:
Dim i As Integer = 0
While (i < ar.Count)
Dim c() As Char = Ctype(ar(i),char())
Console.WriteLine(String.Format("{0} {1} {2}", i, ar.Count, c(0)))
If i = 1 Then
ar.RemoveAt(i)
End If
i += 1
End While
1 commento:
IL MONDO STA ANDANDO ALLA ROVESCIA!
Non riesco a credere all'enorme successo che un linguaggio dal lessico puerile e dalla sintassi incoerente, come C#, stia avendo.
Mi pare ancor più strano che un pregio di VISUAL BASIC possa passare come un difetto.
Mi SPIEGO: Il ciclo iterattivo FOR serve alla iterazione, di un numero fissato di volte, di un gruppo di istruzioni.
Il numero di iterazioni (assolutamento finito e ben determinato) dovrebbe essere specificato nel costrutto FOR tramite una costante.
Per rendere i linguaggi di programmazione più efficienti si è consentito l'uso di variabli o funzioni anche nei cicli FOR.
Tuttavia, proprio per la natura del ciclo FOR, eventuali variabili o funzioni vengono valutate una sola volta, all'inizializzazione del ciclo. Successivamente il costrutto non rivaluta ulteriormente i suddetti valori, come è giusto che sia.
Per l'esecuzione di iterazioni, il cui numero di esecuzioni non è conosciuto a priori o può variare durante l'esecuzione del ciclo, si utilizzano costrutti come WHILE che reiterano un ciclo fino al permanere di una condizione o al verificarsi di una condizione.
Esattamente quello che fa VISUAL BASIC.
Riporto una definizione tratta da WIKIPEDIA: Per rendere agevole l'implementazione di procedure iterative nei linguaggi di programmazione di alto livello, sono disponibili due fondamentali costrutti: for e while. Il primo si presta ai cicli enumerativi (ossia quelli in cui il numero di iterazioni è prestabilito o dipende da un valore numerico calcolato prima dell'iterazione), mentre il secondo permette una libera applicazione della condizione di iterazione.
Oserei pertanto DIRE: ancora un'ennesimo ERRORE (tra le tante brutture) di C# che dovrebbero far riflettere seriamente.
Salvatore FESTA
Posta un commento