08-03-2011, 02:19 AM
Ho trovato qesto articolo girando sul web a casaccio xD, mi sembra molto interesante, anche perché da ciò che leggo, colui che ha scritto questo articolo non parla da solito "nabbo" ma parla da programmatore esperto.
Introduzione
Anni fa, quando fu presentato C# pensai di essere di fronte al linguaggio “definitivo”, semplice, veloce, potente. Forte della sua standardizzazione, C# poteva, forse, essere il linguaggio del futuro. A questo punto, “ruppi il mio salvadanaio” e acquistai due libroni (per la modica cifra di 110 Euro), interamente dedicati a questo linguaggio di programmazione.
Fortunatamente programmo da molti anni con Visual Basic, Visual C++ e PHP e ciò mi ha molto aiutato.
Allo studio di C# affiancai anche quello del nuovo Visual Basic.NET (studiando la sola documentazione ufficiale), ripromettendomi poi di esaminare l'uso di C++.NET non appena concluso il mio "studio comparato" tra VB e C#.
Durante l'apprendimento congiunto dei due linguaggi, non ho potuto fare a meno di paragonarli, per stabilire quale fosse il migliore, e su quale dovessi concentrare i miei sforzi.
Lo studio di C# non ha rappresentato un problema, così come per il nuovo VB.NET. In realtà lo scoglio più grande, non è la sintassi dei linguaggi, bensì l'acquisizione dell'enorme quantità di funzioni fornita dal framework di .NET, fortunatamente comune sia a C# sia a VB.
Dopo molto studio sono finalmente giunto ad una conclusione, ho infatti stabilito quale dei due è, a mio parere, il migliore e il più adatto per lo sviluppo con .NET.
In questo articolo cercherò di spiegare la mia scelta, mostrando quali sono alcuni dei motivi per i quali ritengo Visual Basic.NET, il più semplice e potente linguaggio oggi disponibile per la piattaforma .NET.
Attenzione : Per poter comprendere in maniera completa questo articolo occorre conoscere un minimo il Framework.NET, inoltre è indispensabile la conoscenza (anche minima) di una qualsiasi versione di VB oppure di C#.
La storia
In origine era il Basic, 'antico' linguaggio di programmazione per principianti. Poi, un bel giorno, arrivò Visual Basic.
Da molti punti di vista, si può dire che Visual Basic abbia fatto la storia dei linguaggi 'Visuali' e dei linguaggi di programmazione in genere. E' stato uno dei primi, se non il primo linguaggio a permettere il disegno dell'applicazione, integrando sapientemente l'ambiente di sviluppo con l'editor delle interfacce grafiche.
A Visual Basic si deve la nascita dei componenti VBX e forse, anche dei famigerati oggetti COM/OLE/ActiveX, giunti proprio con l'avvento di Visual Basic 4.
Come se non bastasse, Visual Basic è stato integrato in moltissimi software come linguaggio per la realizzazione di applicativi, il famoso VBA (Visual Basic for Application). Perfino prodotti Open Source come OpenOffice hanno un proprio ambiente di sviluppo, basato sul linguaggio Basic, che tenta di replicare, direi ottimamente, le funzionalità di VBA.
Non dimentichiamo il 'Windows Scripting Host', potente sistema di scripting con supporto per Visual Basic (chiamato Visual Basic Scripting) e Javascript, integrato in tutte le versioni di Windows a partire dalla versione 98. Inoltre come non parlare di 'Internet Explorer', che consente l'utilizzo di Visual Basic in sostituzione a Javascript.
Ricordo poi, per gli amanti di Linux, il progetto Gambas, simile a Visual Basic anche se non vuole esserne un clone. Ha il merito di introdurre un'ottima implementazione dello stile di sviluppo proprio di Visual Basic.
Attualmente, nonostante manchi una vera standardizzazione, Visual Basic è uno dei linguaggi più diffusi ed utilizzati, come si può constatare esaminando i dati forniti da TIOBE nel 'Programming Community Index' .
Dobbiamo sempre ricordare che, apprendere Visual Basic.NET significa avere le basi necessarie per utilizzare VBA (Word, Excel, AutoCAD, IntelliCAD ecc...), OpenOffice Basic, Visual Basic Scripting (con il Windows Scripting Host) e gli script VB in Internet Explorer.
In aggiunta a tutto ciò, saremo anche in grado di sfruttare uno qualsiasi degli altri ambienti basati sul linguaggio BASIC, che è alla base si Visual Basic stesso. Un esempio su tutti è FreeBasic , implementazione multipiattaforma del linguaggio originale, con molte librerie, gestione dell'interfaccia grafica (GTK, Windows nativa, WxWidget, ecc...), compilatore per la generazione di Veri file eseguibili!. Un gran bel lavoro nel pieno rispetto delle regole del "software libero".
Altri esempi possono essere rappresentati da :
Mono's VisualBasic.NET CompilersdlBasic;
sdlBasic, implementazione dedicata alla realizzazione di giochi 2D;
RealBasic, compilatore commerciale potente e facile da utilizzare;
e tanti altri ancora...
Praticamente un linguaggio inserito in una moltitudine di situazioni, semplice, veloce e potente.
Cosa dire invece di C#. Nato da poco, reso standard, è stato presentato come il principe dei linguaggi di programmazione ed è servito a Microsoft per scrivere gran parte delle librerie di .NET. Sintatticamente simile a C++ e Java, appare mirato a catturare i programmatori provenienti da questi linguaggi.
Presente sulla scena da alcuni anni, la sua diffusione ha raggiunto un discreto livello, questo grazie anche alla spinta di Microsoft, e sono state realizzate in C# diverse applicazioni, come ad esempio l'IDE SharpDevelop, oppure il software di fotoritocco Paint.NET
Purtroppo, parte delle mie aspettative sono state disattese, infatti trovo che C# non offra particolari innovazioni o semplificazioni, semplicemente replica cose già viste con altri sistemi e altri linguaggi, lo considero comunque un buon linguaggio.
Passiamo al Confronto
Veniamo ora al confronto vero e proprio tra Visual Basic.NET e C#. Di seguito cercherò di rispondere a questa domanda :
Perchè utilizzare Visual Basic.NET e non C# ?
In questo articolo esaminerò quelle caratteristiche che, a mio parere, rendono VB superiore a C#. Il tutto basandomi sui linguaggi disponibili con il .NET Framework 1.1.
Visual Basic.NET meglio di C#!
Le Istruzioni e il loro terminatore
Iniziamo con una preferenza molto personale. Osserviamo questa riga di codice C# :
C#
a = b + c;
Come si può notare l'istruzione termina con il carattere ';'. Infatti è proprio questo elemento che stabilisce la fine di un'istruzione e l'inizio della successiva, ciò significa che spazi, parentesi, ritorni a capo, non hanno alcuna importanza. Questo ci consente di riscrivere la precedente così :
C#
a
=
b
+
c
;
Queste linee in C# sono perfettamente legali. Naturalmente a nessuno verrebbe mai in mente di scrivere una cosa del genere, però è possibile sfruttare questa caratteristica, volontariamente o involontariamente, per rendere il codice assolutamente illeggibile e difficilmente manutenibile.
Al contrario, Visual Basic prevede, come terminatore, un carattere di fine riga (in realta i caratteri sono due CR+LF). In questo modo, non solo si evita l'inserimento accidentale di istruzioni su più righe ma, nel caso in cui si desideri dividere le istruzioni, permette di identificare in maniera molto chiara il punto nel quale avviene l'interruzione.
Osserviamo questa riga di codice Visual Basic :
VB.NET
a = b + c
In questo caso il ritorno a capo determina la conclusione dell'istruzione. Se però volessimo spezzarla su più righe :
VB.NET
a = _
b + c
Come si può notare, la divisione avviene tramite il carattere '_'. L'uso di questo carattere consente, a chi legge il codice, di identificare immediatamente le linee spezzate, rendendo così il sorgente più chiaro e meno ingannevole.
Lo stile senza parentesi
Anche in questo caso parliamo di chiarezza. Una delle caratteristiche che più apprezzo, quando leggo il codice di un programma è l'uniformità nello stile.
Con i linguaggi derivati da C, come ad esempio C#, posso scrivere :
C#
if (a > 1) {
...
} else {
...
} oppure
if (a > 1)
{
...
}
else
{
...
} oppure
if (a > 1)
{...}
else
{...}
Questa varietà, nonostante consenta di trovare lo stile che più ci aggrada, ci permette di scrivere codice poco uniforme al punto da rendere la lettura difficoltosa, soprattutto quando sono più persone che collaborano allo sviluppo del medesimo programma.
Al contrario Visual Basic.NET, ci aiuta nel rendere uniforme ciò che scriviamo. Infatti possiamo solo scrivere :
VB.NET
If (a > 1) Then
...
Else
...
End If
Tutto qui!
Pensiamo ora ad un codice molto lungo, nel quale si annidano, gli uni negli altri cicli e strutture come 'If', 'While', 'For', ecc... Nella mia cariera, più di una volta, mi è capitato di trovarmi di fronte a cose del genere (C/C++/C#) :
C#
...
}
}
}
}
}
Ovviamente ci si chiederà, cosa terminano queste parentesi ? Quale chiude l'If' ? Quale il 'While'? ecc...
Con i moderni editor di testo, si giunge presto alla risposta andando a ricercare la parentesi aperta corrispondente.
Con Visual Basic.NET questo problema si riduce al minimo, infatti :
VB.NET
...
End If
Next i
End While
End If
End Sub
Nonostante io abbia scritto un po di più, ho il vantaggio di capire quale costrutto termina, senza essere costretto a ricercare il suo inizio, addirittura nel caso del costrutto 'For..Next' conosco anche la viriabile sulla quale si sta agendo.
Il linguaggio Sensibile alle MAIUSCOLE/minuscole
Parliamo ora di MAIUSCOLE e minuscole. C# è un chiaro esempio di linguaggio 'case sensitive', ciò significa che chiamare la funzione 'miafun' è diverso che chiamare 'Miafun' o 'miaFun'.
Al contrario, per Visual Basic, chiamare una variabile 'miavar', 'Miavar' o 'MIAVar' non fa alcuna differenza. Questo comportamento, nonostante consenta di scrivere codice poco uniforme, ha il grande vantaggio di non costringere il programmatore a ricordare la sintassi esatta dei nomi di varibili, funzioni, metodi, proprietà, permettendo ad esempio, l'uso di editor non specializzati per scrivere il codice, oppure evitando inutili ricompilazioni dovute all'inserimento di una maiuscola al posto di una minuscola. Inoltre tale caratteristica rende VB un perfetto candidato ad essere anche un linguaggi di scripting.
In aggiunta a tutto ciò sussiste, nell'utilizzo pratico, un problema con C#.
La specifiche CLS (Common Language Specification) di .NET, prevedono che :
"Perché due identificatori vengano considerati distinti, occorre che non differiscano solo per la combinazione di caratteri maiuscoli o minuscoli."
Ciò significa che, se scrivo una classe con C#, la quale contiene due metodi, 'MetodoMio' e 'metodomio', questa potrà essere usata con altri linguaggi (es. Visual Basic.NET), ma il suo metodo 'MetodoMio' NON potrà mai essere richiamato.
Ovviamente, Visual Basic.NET non presenta questo inconveniente, impedendo la creazione di due metodi con lo stesso nome (ignorando maiuscole e minuscole)
Dichiarazione variabili ed operatore New
Una delle caratteristiche che più apprezzo di Visual Basic.NET è la sua 'descrittività'.
Osserviamo questo codice C# :
C#
Int valint;
String valstr;
Decimal valdec;
bool valbol;
E ora osserviamo il corrispondente Visual Basic.NET :
VB.NET
Dim valint as Integer
Dim valstr as String
Dim valdec as Decimal
Dim valbol as Boolean
Come si può notare, VB possiede una sintassi molto più descrittiva e chiara, anche per il neofita, al contrario, come per tutti i linguaggi derivati dal C, C# è molto più criptico.
In aggiunta a ciò, Visual Basic consente l'utilizzo dell'opzione 'Option Explicit Off' che permette di non dichiarare le variabili.
Ad esempio :
VB.NET
a = "roberto"
System.Console.WriteLine(a)
In questo caso, l'opzione 'Option Explicit Off' consente di utilizzare immediatamente la variabile 'a' senza alcuna dichiarazione. Omettendo l'impostazione di 'Option Explicit', verrà automaticamente impostata a 'On'.
Passiamo ora ad esaminare l'uso della parola chiave 'New' che permette di instanziare un'oggetto.
Per C# :
C#
ArrayList myAL = new ArrayList();
oppure
ArrayList myAL;
myAL = new ArrayList();
Per Visual Basic.NET :
VB.NET
Dim myAL As ArrayList = New ArrayList()
oppure
Dim myAL As ArrayList
myAL = New ArrayList()
oppure
Dim myAL As New ArrayList()
Visual Basic.NET, non solo permette l'uso di 'New' esattamente come C#, ma eredita dal vecchio Visual Basic 6, un terzo tipo di dichiarazione, più breve e più chiaro.
Inizializzazione automatica delle variabili
Siamo giunti ad una delle cose che preferisco di Visual Basic.NET, l'inizializzazione automatica delle varibili. Caratteristica presente in molti altri linguaggi (es.: PHP, Lisp, ecc...).
Osserviamo questo spezzone di codice VB :
VB.NET
Dim i as Integer
While (i < 10)
System.Console.WriteLine(i)
i+=1
End While
In questo caso il ciclo stamperebbe i numeri da 0 a 9, infatti, VB inizializza automaticamente le variabili all'atto della loro dichiarazione. Questo comportamente, non solo consente di scrivere meno, ma riduce anche il codice superfluo presente nei listati.
Con C# al contrario, il seguente codice :
C#
int i;
while (i < 10)
{
System.Console.WriteLine(i)
i++
}
Produce questo errore :
error CS0165: Utilizzo della variabile locale 'i' non assegnata.
Ciò è dovuto al fatto che 'i' deve essere, tassativamente, inizializzata (es. : int i=0.
Conversione dei tipi
La caratteristica che esamineremo ora, consente a Visual Basic.NET la conversione automatica tra tipi di dati che potrebbero comportare perdite di dati e tutte le conversioni tra tipi numerici e stringhe.
Utilizzando l'istruzione 'Option Strict Off' possiamo scrivere :
VB.NET
Dim a As String
Dim b As Integer
b = 3
a = b
In questo caso la conversione da Intero a Stringa è completamente automatica.
Al contrario utilizzando 'Option Strict On', sarà necessario utilizzare una conversione esplicita :
VB.NET
Dim a As String
Dim b As Integer
b = 3
a = CStr(b)
Al contrario in C# non esiste alcuna possibilità di scelta, tutte le conversioni devono essere solo ed esclusivamente Esplicite.
Array e ReDim
Sia Visual Basic.NET, sia C# consentono l'utilizzo di array a uno o più dimensioni.
Nonostante ciò VB possiede alcune caratteristiche, molto utili, che lo distinguono da C#.
Osserviamo questo codice :
VB.NET
Dim s(5) As String
s(5) = "Roberto"
Prima di tutto bisogna notare che, il numero racchiuso tra parentesi nella dichiarazione, rappresenta l'indice massimo utilizzabile e non, come in C#, il numero di elementi dell'array.
Ciò può sembrare strano ma, al contrario è molto logico. Infatti, in tutto il codice si fa riferimento sempre e soltano all'indice dell'array che si vuole leggere o impostare, di conseguenza perchè mai, durante la sua dichiarazione, dovrei utilizzare un indice che in realtà non esiste? Mi pare molto più comodo utilizzare l'indice dell'ultimo elemento valido dell'array. Ricordandomi che, comunque, l'elemento con indice minore è sempre il numero 0.
Altra caratteristica unica di VB è l'uso di REDIM, ad esempio :
VB.NET
Dim s(5) As String
...
ReDim s(10)
In questo caso, l'array 's' viene ridimensionato passando da 6 (0..5) a 11 (0..10) elementi. Dopo il ridimensionamento, 's' sarà un array completamente vuoto. La cosa interessante è però questa :
VB.NET
Dim s(5) As String
...
ReDim Preserve s(10)
Come nel precedente caso l'array 's' viene ridimensionato, con la differenza che, questa volta, gli elementi in esso contenuti non scompaiono ma vengono 'Preservati'. In pratica gli elementi presenti nel vecchio 's' vengono copiati all'interno del nuovo array.
Gli Operatori di Confronto
Anche in questo caso parliamo di chiarezza e leggibilità. Trovo infatti le espressioni di confronto, scritte in Visual Basic.NET, molto più chiare ed immediate, mentre C# presenta la sua solita sintassi criptica.
Ad Esempio, C# :
C#
if ((a < 1) && (b < 1)) //Operatore 'and' (&&)
if ((a < 1) (b < 1)) //Operatore 'or' ()
if !(a < 1) //Negazione booleana 'not' (!)
if (a == 1) // Uguale (==)
if (a != 1) // Diverso (!=)
e per Visual Basic.NET :
VB.NET
if ((a < 1) And (b < 1)) Then 'Operatore 'and'
if ((a < 1) Or (b < 1)) Then 'Operatore 'or'
if Not(a < 1) Then 'Negazione booleana 'not'
if (a = 1) Then 'Uguale (=)
if (a <> 1) Then 'Diverso (<>)
Confronto fra Stringhe
Può apparire strano ma anche il modo di confrontare due stringe pone VB.NET un gradino sopra C#.
In tutti i linguaggi di programmazione, se noi confrontassimo queste due stringhe :
"miastringa" "MiaStringa"
il programma ci direbbe che queste sono diverse. C# e VB.NET si comportano esattamente così.
Visual Basic.NET, nel corso degli anni ha dovuto adattarsi alle richieste degli sviluppatore ed è cresciuto molto. Durante questa evoluzione sono state introdotte molte istruzioni, una delle quali è 'Option Compare'.
Tale istruzione specifica il metodo di confronto delle stringhe, e può essere di tipo binario (Binary) o testuale (Text). Se non è presente 'Option Compare', viene utilizzato Binary come metodo di confronto predefinito.
Se ne deduce che inserendo 'Option Compare Text', il confronto tra le due stringhe precedenti ci dirà che queste sono identiche!
Infatti la modalità di confronto 'Text' prevede questo ordinamento :
(A=a) < ( À=à) < (B=b) < (E=e) < (Ê=ê) < (Z=z) < (Ø=ø)
Mentre 'Binary' :
A < B < E < Z < a < b < e < z < À < Ê < Ø < à < ê < ø
L'opzione 'Option Compare' può essere utilizzata all'interno dei singoli file, ciò fornisce al programmatore una maggiore flessibilità.
L'utile With
Funzionalità presente nel solo Visual Basic.NET, l'istruzione With...End With consente di eseguire una serie di istruzioni su un oggetto specificato senza che sia necessario riqualificare il nome dell'oggetto.
Ad Esempio :
VB.NET
With Label1
.Height = 1000
.Width = 5000
.Text = "Questa è la mia Label"
End With
In questo modo si evita di riscrivere più volte il nome dell'oggetto, rendendo il codice più chiaro e privo di inutili ripetizioni.
La Cortocircuitazione
In C#, utilizzando istruzioni composte viene sempre impiegata una tecnica chiamata 'cortocircuitazione'. Questa consiste nell'eseguire solamente le parti necessarie, tralasciando ciò che è superfluo.
Per maggiore chiarezza, facciamo un esempio :
C#
if ( (a == 1) || (b == 2) )
{
...
}
La condizione valutata è composta da due parti, se la prima parte risultasse vera (a==1) C# NON valuterebbe mai la seconda parte ed eseguirebbe il codice interno al costrutto 'if'.
In Visual Basic.NET :
VB.NET
if ( (a = 1) Or (b = 2) ) then
...
End If
In questo caso, prima vengono valutate entrambe le parti della condizione, e subito dopo viene stabilito se eseguire o meno il codice interno.
Ciò non significa che VB.NET manchi della cortocircuitazione, al contrario permette al programmatore di scegliere quale metodo utilizzare. Infatti troviamo due nuovi operatori, 'AndAlso' e 'OrAlso', che permettono l'uso della tecnica in questione. Quindi, riscrivendo l'esempio :
VB.NET
if ( (a = 1) OrAlso (b = 2) ) then
... End If
L'aggiunta di questi operatori, oltre a consentire una compatibilità con il passato (VB6 e precedenti), permette una maggiore flessibilità rispetto ad altri linguaggi (es.: C#).
Select Case, Intervalli ed Espressioni Multiple
Sia in C# che in Visual Basic.NET è possibile disporre di un'istruzione che gestisce più selezioni trasferendo il controllo a una delle istruzioni 'case' presenti nel corpo.
Sto parlando di 'switch' (C#) e di 'Select Case' (VB.NET). Osserviamo questi esempi :
C#
switch(n)
{
case 1:
a = 1;
break;
case 2:
a = 2;
break;
default:
Console.WriteLine("N non valido.");
break;
}
VB.NET
Select N
Case 1
Console.WriteLine("N = 1")
Case 1 To 5
Console.WriteLine("N compreso fra 2 e 5")
Case 6, 7, 8
Console.WriteLine("N = 6 o 7 o 8")
Case Is > 8
Console.WriteLine("N > 8")
Case Else
Console.WriteLine("N non valido!")
End Select
In C# ogni espressione specificata nell'istruzione 'case' è un semplice valore, al contrario in VB.NET può essere un valore (stringa, intera, ecc..), può essere un intervallo (To), può essere una condizione (Is), addirittura è possibile combinare i vari tipi. Ad Esempio :
VB.NET
Case 1 To 4, 7 To 9, 11, 13, Is > 50
oppure
Case "mela", "a" To "z", ElementoTest
In questo caso Visual Basic.NET dimostra la sua estrema flessibilià, potenza, semplicità e soprattutto chiarezza nelle espressioni. C# invece rimane ancorato alle classiche strutture C/C++/Java senza introdurre alcun miglioramento significativo.
For Each
Entrambe i linguaggi dispongono di un'istruzione per permette di scorrere un'array o un'insieme di oggetti, esaminandone un'elemento alla volta.
In C# troviamo 'Foreach', mentre in VB.NET 'For Each'. Il loro funzionamente è molto simile, l'unica differenza risiede nella capacità di VB.NET di impostare la variabile nella quale, di volta in volta, vengono posti gli elementi analizzati.
Osserviamo questo esempio :
VB.NET
Dim Nazioni(20) As String
Dim NomeNazione As String
For Each NomeNazione In Nazioni
If NomeNazione = "" Then
NomeNazione = "Italia"
End If
System.Console.WriteLine(NomeNazione)
Next NomeNazione
Si osservi che la variabile 'NomeNazione' può essere modificata all'interno del 'For Each', questo senza intaccare i dati presenti nell'array esaminato. Tale interessante caratteristica è assente in C#, che di fatto segnala un errore.
La Gestione dell'Errore
In questo campo VB.NET e C# appaiono, ad una prima analisi, molto simili. Entrambe gestiscono gli errori con i costrutti 'throw', 'try-catch', 'try-finally', 'try-catch-finally'.
Ciò che li distingue e che semplifica la vita agli sviluppatori VB.NET è la presenza, in questo linguaggio, dell'istruzione 'On Error'. Derivata dalle precedenti versioni, 'On Error' consente di attivare una routine di gestione degli errori e di specificarne la posizione all'interno di una routine più ampia, permettendo inoltre di disattivare una routine di gestione degli errori precedentemente attivata.
Chi volesse utilizzare una gestione semplificata dell'errore, troverà in 'On Error' una valida soluzione.
Vista la varietà di usi che si possono fare di 'On Error', per gli esempi si consulti la documentazione ufficiale :
Microsoft MSDN
Le Funzioni
Molte cose ci sarebbero da dire sulle funzioni. VB.NET permette alcuni utilizzi non previsti da C#.
Prima di tutto, con Visual Basic.NET è superfluo indicare il valore ritornato dalle funzioni se questo è nullo ("" per le stringhe, 0 per i numeri, ecc...), infatti se si omette l'istruzione 'return', la funzione restituirà proprio 0, "", ecc... a seconda del tipo di dato.
Ad esempio :
VB.NET
Function TestFx (retA As Boolean) As Integer
Dim a As Integer
If (retA) Then
a = 1
Return a
End If
End Function
In questo caso, la funzione restituirà 0 se 'retA=False', altrimenti ritornerà 1.
L'uso sapiente di questo automatismo consente di minimizzare l'uso dell'istruzione 'Return', rendendo più semplice e scorrevole la lettura del codice, riuscendo a focalizzare l'attenzione sui dati più significativi.
Un'altra particolare caratteristica di Visual Basic.NET è quella di disporre di un sistema alternativo a 'Return'. All'interno delle funzioni è disponibile una variabile che possiede lo stesso nome della funzione, settando la quale, di fatto si imposta il valore da restituire.
Ad esempio, riscrivendo la funzione precedente :
VB.NET
Function TestFx (retA As Boolean) As integer
Dim a As Integer
If (retA) Then
a = 1
TestFx = a
End If
End Function
Per concludere il discorso, non bisogna dimenticare i parametri opzionali. E' infatti possibile definire alcuni parametri come opzionali, ciò permette la loro omissione nella chiamata della funzione.
Ad esempio :
VB.NET
Sub TestFx (par1 As Integer, _
Optional par2 as String = "", _
Optional par3 as Boolean = True)
...
End Sub
In questo esempio 'par2' e 'par3' sono dichiarati opzionali, ciò significa che all'atto della chiamata potremo, a nostra discrezione, indicare o meno i loro valori.
Il modificatore 'Optional', risulta particolarmente utile per semplificare l'uso di funzioni complesse senza dover ricorrere all'overloading. 'Optional' NON è presente in C# ma solo in VB.NET.
I Comandi Visual Basic
Come accade in molti altri linguaggi, Visual Basic.NET possiede una nutrita serie di funzioni, proprietà, metodi, tipi e costanti facenti parte della sua libreria di runtime. Queste, vanno ad aggiungersi alle classi proprie del framework di .NET.
L'uso delle funzioni interne di VB.NET consente, al programmatore, la semplificazione di molte operazione che altrimenti, dovrebbero essere svolte tramite l'uso delle classi del framework.
Per comprendere meglio l'utilità delle funzioni integrate nel runtime di VB.NET osserviamo quanto segue :
VB.NET
'Finestra di messaggio utilizzata attraverso le classi del framework
MessageBox.Show(Me, "Messaggio", "Titolo", MessageBoxButtons.YesNo, _
MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, _
MessageBoxOptions.RightAlign)
'Finestra di messaggio utilizzata attraverso le classi di runtime di VB.NET
MsgBox("Messaggio", vbYesNo Or vbQuestion Or _
vbDefaultButton1 Or vbMsgBoxRight, "Titolo")
Come si può notare l'utilizzo delle funzioni e delle costanti di runtime, semplifica enormemente l'istruzione rendendola molto più chiara ed immediata.
C#, nonostante sia in grado di utilizzare anche le funzioni proprie di VB.NET (in maniera decisamente più macchinosa), non dispone di una propria libreria di runtime.
Using e Imports
In .NET l'organizzazione dei programmi C#, VB, ed in genere qualsiasi altro linguaggio basato su questa piattaforma, si poggia sull'uso degli spazi dei nomi. Questi vengono utilizzati sia come sistema organizzativo "interno" che come sistema organizzativo "esterno", ovvero come un modo per presentare gli elementi del programma esposti ad altri programmi.
Per semplificare l'utilizzo degli spazi dei nomi (namespace) sono disponibili , in VB e C#, le direttive 'imports', per il primo, e 'using' per il secondo.
Così come in altri casi, anche questa volta Visual Basic.NET si pone un gradino sopra C#.
Sia la direttiva 'Using', sia 'Imports' consentono la creazione di un alias per uno spazio dei nomi e l'uso dei tipi in uno spazio dei nomi, evitando di dover qualificare l'uso di un tipo in tale spazio.
Senza queste istruzioni, per utilizzare l'oggetto 'Console' dovremo scrivere così :
C#
System.Console.WriteLine("Messaggio...");
VB.NET
System.Console.WriteLine("Messaggio...")
Al contrario utilizzando 'Using' e 'Imports', semplificheremmo il tutto :
C#
Using System
Console.WriteLine("Messaggio...");
VB.NET
Imports System
Console.WriteLine("Messaggio...")
Con Visual Basic.NET, e la sua 'Imports', possiamo anche fare di meglio. Infatti 'Imports' consente, non solo l'importazione di spazi di nomi ma anche di classi (come ad esempio la classe 'Console'). Questa importante caratteristica ci consente di far riferimento agli elementi di una classe senza doverla specificare.
Riscrivendo l'esempio precedente :
VB.NET
Imports System.Console
WriteLine("Messaggio...")
Questa possibilità, purtroppo, è completamente assente in C#.
I Moduli
In C# l'elemento principale è la Classe. Tutto è racchiuso al suo interno.
VB.NET si spinge oltre, infatti supporta pienamente le Classi (come C#), aggiungendo la possibilità di utilizzare i Moduli.
Questi rappresentano un tipo di riferimento simile alle classi, dalle quali si distinguono però per alcune caratteristiche significative. I loro membri sono, in modo implicito, di tipo 'Shared' (identico allo 'static' di C# )e il loro ambito è limitato allo spazio di dichiarazione dello spazio dei nomi in cui il modulo è dichiarato. A differenza delle classi, i moduli non possono essere instanziati, non supportano l'ereditarietà e non possono implementare interfacce. Un modulo può solamente essere dichiarato in uno spazio dei nomi.
Naturalmente, all'interno dello stesso progetto possono essere presenti più moduli.
Una cosa interessante è che i moduli possono essere esportati, esattamente come le classi, e utilizzati da altri linguaggi.
All'atto pratico un modulo può essere paragonato ad una libreria di variabili, proprietà, eventi, metodi e funzioni in genere.
I Membri Shared
Vengono chiamati metodi condivisi. Sono disponibili sia in C# (usando il modificatore 'Static'), sia in VB.NET (usando il modificatore 'Shared').
Questi metodi non agiscono su una specifica istanza di un tipo e possono essere richiamati direttamente dal tipo anziché attraverso una particolare istanza.
Facciamo un esempio di metodo condiviso :
C#
Class Test
{
private int x;
public static int fxCondivisa()
{
return x;
}
}
Class App
{
public static void Main()
{
int valx;
Test t = New Test();
valx = Test.fxCondivisa();
valx = t.fxCondivisa(); //ERRORE!!!
}
}
VB.NET
Class Test
Private x As Integer
Shared Function fxCondivisa() As Integer
return x
End Function
End Class
Shared Sub Main()
Dim valx As Integer
Dim t As New Test()
valx = Test.fxCondivisa()
valx = t.fxCondivisa()
End Sub
Ciò che VB.NET è in grado di fare, e C# no, è utilizzare i membri 'shared' attraverso l'istanza degli oggetti e non solo attraverso il tipo. Si può in pratica affermare che gli elementi 'shared' sono parte effettiva sia del tipo, sia delle sue istanze.
Avviare i Programmi
Con .NET, l'avvio di un programma avviene attraverso il metodo 'Main'. Indipendentemente dal linguaggio, il metodo 'Main' viene richiamato immediatamente all'avvio del software. Si può dire che 'tutto parte da qui'.
Esistono diversi tipi di dichiarazione per il metodo 'Main', che solitamente risiede all'interno di una Classe. Vediamo un piccolo esempio :
C#
class AppClass
{
public static int Main(string[] args)
{
...
return 0;
}
}
VB.NET
Class AppClass
Function Main(ByVal Args() As String) As Integer
...
return 0;
End Function
End Class
In entrambe i casi, 'Main' si trova all'interno di una classe e riceve, come parametro, l'elenco degli argomenti passati all'eseguibile.
Oltre ai normali utilizzi, Visual Basic.NET aggiungie una interessante caratteristica.
Con VB.NET è possibile evitare l'uso di una classe sostituendola con un semplice modulo :
VB.NET
Module AppMod
Function Main(ByVal Args() As String) As Integer
...
return 0;
End Function
End Module
Questo consente un approccio procedurale alla programmazione, utile soprattutto per piccoli software, dove la struttura generale ha una rilevanza marginale. Comodo per la crezione di semplici librerie di funzioni e intuitivo per il programmatore alle prime armi.
Proprietà
La definizione delle proprietà all'interno delle classi è fondamentale per la gestione degli oggetti. VB.NET e C# consentono un completo controllo su questo importante aspetto.
Come spesso accade, Visual Basic.NET aggiunge una possibilità in più. Con questo linguaggio è infatti possibile definire delle proprietà dotate di parametri. Ad Esempio :
VB.NET
Imports System
Module TestVB
Class clTest
Private strValore As String
Property valore() As String
Get
Return strValore
End Get
Set (ByVal value As String)
strValore = value
End Set
End Property
Property valore(ByVal tipo as string) as string
Get
Return strValore
End Get
Set (ByVal value As string)
strValore = value + " " + tipo
End Set
End Property
End Class
Sub Main()
Dim testObj As New clTest
'proprietà semplice
testObj.valore = "Roberto"
Console.WriteLine(testObj.valore)
'proprietà con parametro
testObj.valore("Rossi") = "Roberto"
Console.WriteLine(testObj.valore)
End Sub
End Module
Alcuni mi hanno fatto notare che questa caratteristica è presente anche in C#. In realtà non è così. C# consente di utilizzare gli indicizzatori. Questi sono membri che consentono di indicizzare un oggetto come se si trattasse di una matrice. In questo caso però si va ad agire su tutto sull'oggetto e non sulla singola proprietà. E' sottointesto che VB.NET possiede anche questa capacità.
Late Binding
Sia C#, sia VB.NET consentono, durante l'esecuzione di un programma di instanziare un'oggetto dinamicamente e indipendentemente dal suo tipo, potendone ricavare ed utilizzare metodi, proprietà ed eventi. Ciò avviene attrave l'utilizzo della tecnica di Riflessione.
In pratica si ha un'oggetto di tipo 'generico' che può essere assegnato ad un tipo X e quindi, è possibile utilizzare metodi, proprieta ed eventi proprio del tipo X.
Vista la complessità dell'argomento, rimando alla documentazione ufficiale ( La Riflessione).
VB.NET possiede la capacità di utilizzare l'associazione tardiva (Late Binding), che in pratica si affianca al sistema di riflessione e semplifica enormemente l'utilizzo dinamico degli oggetti.
Vediamo un esempio :
VB.NET
Imports System
Module TestVB
Class clTest
Private strValore As String
Public Sub SetValore (ByVal dato As String)
strValore = dato
Console.WriteLine(dato)
End Sub
End Class
Sub Main()
Dim testObj As Object 'tipo generico
testObj = New clTest
testObj.SetValore("Esempio...")
End Sub
End Module
Come si può intuire, utilizzare un oggetto di tipo generico (Object), e poi utilizzarlo come se fosse stato convertito in un tipo specifico (clTest), riduce la quantità di codice scritto, rendendo più chiaro e lineare il listato.
Ora applichiamo questa potente funzione di Visual Basic.NET per utilizzare un'istanza di 'Internet Explorer' :
VB.NET
Imports Microsoft.VisualBasic
Module TestVB
Sub Main()
Dim ieObj As Object 'tipo generico
ieObj = CreateObject("InternetExplorer.Application")
ieObj.MenuBar = false
ieObj.Visible = true
ieObj.Navigate("http://rsoftware.altervista.org")
End Sub
End Module
Quest'ultimo utilizzo del 'late binding', associato agli oggetti ActiveX, permette il rapido e semplice riutilizzo di una moltitudine di componenti e applicazione già esistenti (es.: Excel, Word, OpenOffice, AutoCAD ecc...).
Putroppo il 'Late Binding' NON è presente in C#.
Overloading dei Membri nelle Classi
Esistono alcune cose nei linguaggi di programmazioni che mi lasciano molto perplesso.
C#, nuovissimo linguaggio "super moderno", porta con se una triste caratteristica, legata all'ereditarietà.
Osserviamo :
C#
using System;
class AppMain {
public static void Main() {
Derivata objDerivato = new Derivata();
clTest objTest = new clTest();
objDerivato.FunzioneInterna(objTest);
}
}
class clTest
{
//Classe per Test
}
class Principale
{
public virtual void FunzioneInterna (clTest oggetto)
{
Console.WriteLine("Esecuzione FunzioneInterna(clTest) in Classe Principale");
}
}
class Derivata : Principale
{
public override void FunzioneInterna (clTest oggetto)
{
Console.WriteLine("Esecuzione FunzioneInterna(clTest) in Classe Derivata");
}
public void FunzioneInterna (object oggetto)
{
Console.WriteLine("Esecuzione FunzioneInterna(object) in Classe Derivata");
}
}
Il risultato prodotto al prompt dei comandi :
Esecuzione FunzioneInterna(object) in Classe Derivata
Esaminando il codice si vede, charamente, che l'oggetto objTest (di tipo clTest), passato al metodo FunzioneInterna della classe Derivata, esegue "FunzioneInterna(object oggetto)". La cosa strana è che, all'interno della classe Derivata è presente un'altro metodo FunzioneInterna che accetta esattamente il tipo di dato di objTest (tipo clTest). Perchè non viene richiamato questo metodo, visto che è decisamente più compatibile con il dato passato ? Ma?!?! Non mi capacito.
Evidentemente C# porta con se l'eredità di C++ che funziona esattamente allo stesso modo.
Visual Basic.NET al contrario, si comporta esattamente come vorrebbe la logica. Osserviamo lo stesso esempio :
VB.NET
Imports System
Module TestVB
Sub Main()
Dim objDerivato As New Derivata
Dim objTest As New clTest
objDerivato.FunzioneInterna(objTest)
End Sub
End Module
Class clTest
'Classe per Test
End Class
Class Principale
Public Overridable Sub FunzioneInterna(oggetto As clTest)
Console.WriteLine("Esecuzione FunzioneInterna(clTest) in Classe Principale")
End Sub
End Class
Class Derivata : Inherits Principale
Public Overloads Overrides Sub FunzioneInterna (oggetto As clTest)
Console.WriteLine("Esecuzione FunzioneInterna(clTest) in Classe Derivata")
End Sub
Public Overloads Sub FunzioneInterna (oggetto As Object)
Console.WriteLine("Esecuzione FunzioneInterna(object) in Classe Derivata")
End Sub
End Class
Il risultato prodotto al prompt dei comandi :
Esecuzione FunzioneInterna(clTest) in Classe Derivata
Logicamente, passando l'oggetto objTest (tipo clTest) al metodo FunzioneInterna presente nella classe Derivata, viene richiamato il metodo più compatibile con il tipo di dato utilizzato.
Considerazioni Finali
Per concludere, ecco la fatidica domanda. Usare Visual Basic.NET o C#?
Secondo il mio parere, dipende da quali conoscenze di base si hanno e da quali progetti si vogliono realizzare.
Se non si hanno esperienze di programmazione, la strada migliore è quella di VB.NET. Più intuitivo e semplice, può sfruttare completamente le funzionalità di .NET.
Se si proviene da vecchie versioni di Visual Basic, e non si vuole perdere tempo per nulla, la scelta più sensata è VB.NET.
Se si programma in Java, passando a C# si semplifica la migrazione, avendo quest'ultimo una sintassi in stile C++.
Conoscendo C/C++ la questione è più complessa. Da un lato la migrazione a C# sarebbe più semplice, però bisogna considerare che C++ consente l'utilizzo del Framework .NET senza bisogno di cambiare linguaggio. Ciò, dal mio punto di vista, significa che chi sviluppa con C++ avrebbe maggiori vantaggi a continuare su questa strada aggiungendo le conoscenze sulle librerie .NET. Inoltre non dimentichiamoci che, comunque, l'uso di C/C++ è ancora indispensabile in una moltitudine di casi, soprattutto quando si vogliono realizzare applicazioni particolarmente pesanti (es.: software di CAD), magari da far girare du PC non molto potenti, o più semplicemente se si desidera integrare particolari procedure (Es.: codice assembler). Si tenga anche presente che C/C++ è l'unico linguaggio a poter compilare i software senza la necessita di installare il Framework.NET.
Per gli utilizzatori di altri linguaggi (es.: Delphi, Lisp, ecc...), soprattutto quelli che non possiedono una sintassi simile a C/C++, e che desiderano sviluppare con i prodotti Microsoft, VB.NET rappresenta la scelta più azzeccata, sufficientemente semplice, descrittivo, chiaro e con tutta la potenza di .NET.
Se si desidera sviluppare software per Linux, la scelta attualmente appare obbligata, C#. I due progetti principali di porting di .NET su Linux, comprendono solo compilatori C# e C. Nello specifico sto parlando di :
Mono
DotGNU
Bisogna però dire che sono già in preparazione compilatori Visual Basic.NET anche per questi progetti. Ad esempio, il progetto Mono prevede l'introduzione del compilatore VB.NET già nell'anno in corso (2005).
Infine parliamo di prestazioni. Questa volta Microsoft ha detto il vero. A parità di funzioni utilizzate, che il software venga sviluppato con Visual Basic.NET o C#, le prestazioni non cambiano di una 'virgola'.
Chi volesse fornire il suo contributo con, critiche, suggerimenti, aggiunte, segnalazioni di errore, ecc... può farlo cliccando qui.
Copyright e autorizzazione:
Copyright 2005-2009 Roberto Rossi
Web : http://www.redchar.net
La copia di questo articolo e la sua distribuzione sono permessi in qualsiasi forma senza il pagamento di diritti di autore a patto che l'indicazione del copyright e questa indicazione siano riportate.
Introduzione
Anni fa, quando fu presentato C# pensai di essere di fronte al linguaggio “definitivo”, semplice, veloce, potente. Forte della sua standardizzazione, C# poteva, forse, essere il linguaggio del futuro. A questo punto, “ruppi il mio salvadanaio” e acquistai due libroni (per la modica cifra di 110 Euro), interamente dedicati a questo linguaggio di programmazione.
Fortunatamente programmo da molti anni con Visual Basic, Visual C++ e PHP e ciò mi ha molto aiutato.
Allo studio di C# affiancai anche quello del nuovo Visual Basic.NET (studiando la sola documentazione ufficiale), ripromettendomi poi di esaminare l'uso di C++.NET non appena concluso il mio "studio comparato" tra VB e C#.
Durante l'apprendimento congiunto dei due linguaggi, non ho potuto fare a meno di paragonarli, per stabilire quale fosse il migliore, e su quale dovessi concentrare i miei sforzi.
Lo studio di C# non ha rappresentato un problema, così come per il nuovo VB.NET. In realtà lo scoglio più grande, non è la sintassi dei linguaggi, bensì l'acquisizione dell'enorme quantità di funzioni fornita dal framework di .NET, fortunatamente comune sia a C# sia a VB.
Dopo molto studio sono finalmente giunto ad una conclusione, ho infatti stabilito quale dei due è, a mio parere, il migliore e il più adatto per lo sviluppo con .NET.
In questo articolo cercherò di spiegare la mia scelta, mostrando quali sono alcuni dei motivi per i quali ritengo Visual Basic.NET, il più semplice e potente linguaggio oggi disponibile per la piattaforma .NET.
Attenzione : Per poter comprendere in maniera completa questo articolo occorre conoscere un minimo il Framework.NET, inoltre è indispensabile la conoscenza (anche minima) di una qualsiasi versione di VB oppure di C#.
La storia
In origine era il Basic, 'antico' linguaggio di programmazione per principianti. Poi, un bel giorno, arrivò Visual Basic.
Da molti punti di vista, si può dire che Visual Basic abbia fatto la storia dei linguaggi 'Visuali' e dei linguaggi di programmazione in genere. E' stato uno dei primi, se non il primo linguaggio a permettere il disegno dell'applicazione, integrando sapientemente l'ambiente di sviluppo con l'editor delle interfacce grafiche.
A Visual Basic si deve la nascita dei componenti VBX e forse, anche dei famigerati oggetti COM/OLE/ActiveX, giunti proprio con l'avvento di Visual Basic 4.
Come se non bastasse, Visual Basic è stato integrato in moltissimi software come linguaggio per la realizzazione di applicativi, il famoso VBA (Visual Basic for Application). Perfino prodotti Open Source come OpenOffice hanno un proprio ambiente di sviluppo, basato sul linguaggio Basic, che tenta di replicare, direi ottimamente, le funzionalità di VBA.
Non dimentichiamo il 'Windows Scripting Host', potente sistema di scripting con supporto per Visual Basic (chiamato Visual Basic Scripting) e Javascript, integrato in tutte le versioni di Windows a partire dalla versione 98. Inoltre come non parlare di 'Internet Explorer', che consente l'utilizzo di Visual Basic in sostituzione a Javascript.
Ricordo poi, per gli amanti di Linux, il progetto Gambas, simile a Visual Basic anche se non vuole esserne un clone. Ha il merito di introdurre un'ottima implementazione dello stile di sviluppo proprio di Visual Basic.
Attualmente, nonostante manchi una vera standardizzazione, Visual Basic è uno dei linguaggi più diffusi ed utilizzati, come si può constatare esaminando i dati forniti da TIOBE nel 'Programming Community Index' .
Dobbiamo sempre ricordare che, apprendere Visual Basic.NET significa avere le basi necessarie per utilizzare VBA (Word, Excel, AutoCAD, IntelliCAD ecc...), OpenOffice Basic, Visual Basic Scripting (con il Windows Scripting Host) e gli script VB in Internet Explorer.
In aggiunta a tutto ciò, saremo anche in grado di sfruttare uno qualsiasi degli altri ambienti basati sul linguaggio BASIC, che è alla base si Visual Basic stesso. Un esempio su tutti è FreeBasic , implementazione multipiattaforma del linguaggio originale, con molte librerie, gestione dell'interfaccia grafica (GTK, Windows nativa, WxWidget, ecc...), compilatore per la generazione di Veri file eseguibili!. Un gran bel lavoro nel pieno rispetto delle regole del "software libero".
Altri esempi possono essere rappresentati da :
Mono's VisualBasic.NET CompilersdlBasic;
sdlBasic, implementazione dedicata alla realizzazione di giochi 2D;
RealBasic, compilatore commerciale potente e facile da utilizzare;
e tanti altri ancora...
Praticamente un linguaggio inserito in una moltitudine di situazioni, semplice, veloce e potente.
Cosa dire invece di C#. Nato da poco, reso standard, è stato presentato come il principe dei linguaggi di programmazione ed è servito a Microsoft per scrivere gran parte delle librerie di .NET. Sintatticamente simile a C++ e Java, appare mirato a catturare i programmatori provenienti da questi linguaggi.
Presente sulla scena da alcuni anni, la sua diffusione ha raggiunto un discreto livello, questo grazie anche alla spinta di Microsoft, e sono state realizzate in C# diverse applicazioni, come ad esempio l'IDE SharpDevelop, oppure il software di fotoritocco Paint.NET
Purtroppo, parte delle mie aspettative sono state disattese, infatti trovo che C# non offra particolari innovazioni o semplificazioni, semplicemente replica cose già viste con altri sistemi e altri linguaggi, lo considero comunque un buon linguaggio.
Passiamo al Confronto
Veniamo ora al confronto vero e proprio tra Visual Basic.NET e C#. Di seguito cercherò di rispondere a questa domanda :
Perchè utilizzare Visual Basic.NET e non C# ?
In questo articolo esaminerò quelle caratteristiche che, a mio parere, rendono VB superiore a C#. Il tutto basandomi sui linguaggi disponibili con il .NET Framework 1.1.
Visual Basic.NET meglio di C#!
Le Istruzioni e il loro terminatore
Iniziamo con una preferenza molto personale. Osserviamo questa riga di codice C# :
C#
a = b + c;
Come si può notare l'istruzione termina con il carattere ';'. Infatti è proprio questo elemento che stabilisce la fine di un'istruzione e l'inizio della successiva, ciò significa che spazi, parentesi, ritorni a capo, non hanno alcuna importanza. Questo ci consente di riscrivere la precedente così :
C#
a
=
b
+
c
;
Queste linee in C# sono perfettamente legali. Naturalmente a nessuno verrebbe mai in mente di scrivere una cosa del genere, però è possibile sfruttare questa caratteristica, volontariamente o involontariamente, per rendere il codice assolutamente illeggibile e difficilmente manutenibile.
Al contrario, Visual Basic prevede, come terminatore, un carattere di fine riga (in realta i caratteri sono due CR+LF). In questo modo, non solo si evita l'inserimento accidentale di istruzioni su più righe ma, nel caso in cui si desideri dividere le istruzioni, permette di identificare in maniera molto chiara il punto nel quale avviene l'interruzione.
Osserviamo questa riga di codice Visual Basic :
VB.NET
a = b + c
In questo caso il ritorno a capo determina la conclusione dell'istruzione. Se però volessimo spezzarla su più righe :
VB.NET
a = _
b + c
Come si può notare, la divisione avviene tramite il carattere '_'. L'uso di questo carattere consente, a chi legge il codice, di identificare immediatamente le linee spezzate, rendendo così il sorgente più chiaro e meno ingannevole.
Lo stile senza parentesi
Anche in questo caso parliamo di chiarezza. Una delle caratteristiche che più apprezzo, quando leggo il codice di un programma è l'uniformità nello stile.
Con i linguaggi derivati da C, come ad esempio C#, posso scrivere :
C#
if (a > 1) {
...
} else {
...
} oppure
if (a > 1)
{
...
}
else
{
...
} oppure
if (a > 1)
{...}
else
{...}
Questa varietà, nonostante consenta di trovare lo stile che più ci aggrada, ci permette di scrivere codice poco uniforme al punto da rendere la lettura difficoltosa, soprattutto quando sono più persone che collaborano allo sviluppo del medesimo programma.
Al contrario Visual Basic.NET, ci aiuta nel rendere uniforme ciò che scriviamo. Infatti possiamo solo scrivere :
VB.NET
If (a > 1) Then
...
Else
...
End If
Tutto qui!
Pensiamo ora ad un codice molto lungo, nel quale si annidano, gli uni negli altri cicli e strutture come 'If', 'While', 'For', ecc... Nella mia cariera, più di una volta, mi è capitato di trovarmi di fronte a cose del genere (C/C++/C#) :
C#
...
}
}
}
}
}
Ovviamente ci si chiederà, cosa terminano queste parentesi ? Quale chiude l'If' ? Quale il 'While'? ecc...
Con i moderni editor di testo, si giunge presto alla risposta andando a ricercare la parentesi aperta corrispondente.
Con Visual Basic.NET questo problema si riduce al minimo, infatti :
VB.NET
...
End If
Next i
End While
End If
End Sub
Nonostante io abbia scritto un po di più, ho il vantaggio di capire quale costrutto termina, senza essere costretto a ricercare il suo inizio, addirittura nel caso del costrutto 'For..Next' conosco anche la viriabile sulla quale si sta agendo.
Il linguaggio Sensibile alle MAIUSCOLE/minuscole
Parliamo ora di MAIUSCOLE e minuscole. C# è un chiaro esempio di linguaggio 'case sensitive', ciò significa che chiamare la funzione 'miafun' è diverso che chiamare 'Miafun' o 'miaFun'.
Al contrario, per Visual Basic, chiamare una variabile 'miavar', 'Miavar' o 'MIAVar' non fa alcuna differenza. Questo comportamento, nonostante consenta di scrivere codice poco uniforme, ha il grande vantaggio di non costringere il programmatore a ricordare la sintassi esatta dei nomi di varibili, funzioni, metodi, proprietà, permettendo ad esempio, l'uso di editor non specializzati per scrivere il codice, oppure evitando inutili ricompilazioni dovute all'inserimento di una maiuscola al posto di una minuscola. Inoltre tale caratteristica rende VB un perfetto candidato ad essere anche un linguaggi di scripting.
In aggiunta a tutto ciò sussiste, nell'utilizzo pratico, un problema con C#.
La specifiche CLS (Common Language Specification) di .NET, prevedono che :
"Perché due identificatori vengano considerati distinti, occorre che non differiscano solo per la combinazione di caratteri maiuscoli o minuscoli."
Ciò significa che, se scrivo una classe con C#, la quale contiene due metodi, 'MetodoMio' e 'metodomio', questa potrà essere usata con altri linguaggi (es. Visual Basic.NET), ma il suo metodo 'MetodoMio' NON potrà mai essere richiamato.
Ovviamente, Visual Basic.NET non presenta questo inconveniente, impedendo la creazione di due metodi con lo stesso nome (ignorando maiuscole e minuscole)
Dichiarazione variabili ed operatore New
Una delle caratteristiche che più apprezzo di Visual Basic.NET è la sua 'descrittività'.
Osserviamo questo codice C# :
C#
Int valint;
String valstr;
Decimal valdec;
bool valbol;
E ora osserviamo il corrispondente Visual Basic.NET :
VB.NET
Dim valint as Integer
Dim valstr as String
Dim valdec as Decimal
Dim valbol as Boolean
Come si può notare, VB possiede una sintassi molto più descrittiva e chiara, anche per il neofita, al contrario, come per tutti i linguaggi derivati dal C, C# è molto più criptico.
In aggiunta a ciò, Visual Basic consente l'utilizzo dell'opzione 'Option Explicit Off' che permette di non dichiarare le variabili.
Ad esempio :
VB.NET
a = "roberto"
System.Console.WriteLine(a)
In questo caso, l'opzione 'Option Explicit Off' consente di utilizzare immediatamente la variabile 'a' senza alcuna dichiarazione. Omettendo l'impostazione di 'Option Explicit', verrà automaticamente impostata a 'On'.
Passiamo ora ad esaminare l'uso della parola chiave 'New' che permette di instanziare un'oggetto.
Per C# :
C#
ArrayList myAL = new ArrayList();
oppure
ArrayList myAL;
myAL = new ArrayList();
Per Visual Basic.NET :
VB.NET
Dim myAL As ArrayList = New ArrayList()
oppure
Dim myAL As ArrayList
myAL = New ArrayList()
oppure
Dim myAL As New ArrayList()
Visual Basic.NET, non solo permette l'uso di 'New' esattamente come C#, ma eredita dal vecchio Visual Basic 6, un terzo tipo di dichiarazione, più breve e più chiaro.
Inizializzazione automatica delle variabili
Siamo giunti ad una delle cose che preferisco di Visual Basic.NET, l'inizializzazione automatica delle varibili. Caratteristica presente in molti altri linguaggi (es.: PHP, Lisp, ecc...).
Osserviamo questo spezzone di codice VB :
VB.NET
Dim i as Integer
While (i < 10)
System.Console.WriteLine(i)
i+=1
End While
In questo caso il ciclo stamperebbe i numeri da 0 a 9, infatti, VB inizializza automaticamente le variabili all'atto della loro dichiarazione. Questo comportamente, non solo consente di scrivere meno, ma riduce anche il codice superfluo presente nei listati.
Con C# al contrario, il seguente codice :
C#
int i;
while (i < 10)
{
System.Console.WriteLine(i)
i++
}
Produce questo errore :
error CS0165: Utilizzo della variabile locale 'i' non assegnata.
Ciò è dovuto al fatto che 'i' deve essere, tassativamente, inizializzata (es. : int i=0.
Conversione dei tipi
La caratteristica che esamineremo ora, consente a Visual Basic.NET la conversione automatica tra tipi di dati che potrebbero comportare perdite di dati e tutte le conversioni tra tipi numerici e stringhe.
Utilizzando l'istruzione 'Option Strict Off' possiamo scrivere :
VB.NET
Dim a As String
Dim b As Integer
b = 3
a = b
In questo caso la conversione da Intero a Stringa è completamente automatica.
Al contrario utilizzando 'Option Strict On', sarà necessario utilizzare una conversione esplicita :
VB.NET
Dim a As String
Dim b As Integer
b = 3
a = CStr(b)
Al contrario in C# non esiste alcuna possibilità di scelta, tutte le conversioni devono essere solo ed esclusivamente Esplicite.
Array e ReDim
Sia Visual Basic.NET, sia C# consentono l'utilizzo di array a uno o più dimensioni.
Nonostante ciò VB possiede alcune caratteristiche, molto utili, che lo distinguono da C#.
Osserviamo questo codice :
VB.NET
Dim s(5) As String
s(5) = "Roberto"
Prima di tutto bisogna notare che, il numero racchiuso tra parentesi nella dichiarazione, rappresenta l'indice massimo utilizzabile e non, come in C#, il numero di elementi dell'array.
Ciò può sembrare strano ma, al contrario è molto logico. Infatti, in tutto il codice si fa riferimento sempre e soltano all'indice dell'array che si vuole leggere o impostare, di conseguenza perchè mai, durante la sua dichiarazione, dovrei utilizzare un indice che in realtà non esiste? Mi pare molto più comodo utilizzare l'indice dell'ultimo elemento valido dell'array. Ricordandomi che, comunque, l'elemento con indice minore è sempre il numero 0.
Altra caratteristica unica di VB è l'uso di REDIM, ad esempio :
VB.NET
Dim s(5) As String
...
ReDim s(10)
In questo caso, l'array 's' viene ridimensionato passando da 6 (0..5) a 11 (0..10) elementi. Dopo il ridimensionamento, 's' sarà un array completamente vuoto. La cosa interessante è però questa :
VB.NET
Dim s(5) As String
...
ReDim Preserve s(10)
Come nel precedente caso l'array 's' viene ridimensionato, con la differenza che, questa volta, gli elementi in esso contenuti non scompaiono ma vengono 'Preservati'. In pratica gli elementi presenti nel vecchio 's' vengono copiati all'interno del nuovo array.
Gli Operatori di Confronto
Anche in questo caso parliamo di chiarezza e leggibilità. Trovo infatti le espressioni di confronto, scritte in Visual Basic.NET, molto più chiare ed immediate, mentre C# presenta la sua solita sintassi criptica.
Ad Esempio, C# :
C#
if ((a < 1) && (b < 1)) //Operatore 'and' (&&)
if ((a < 1) (b < 1)) //Operatore 'or' ()
if !(a < 1) //Negazione booleana 'not' (!)
if (a == 1) // Uguale (==)
if (a != 1) // Diverso (!=)
e per Visual Basic.NET :
VB.NET
if ((a < 1) And (b < 1)) Then 'Operatore 'and'
if ((a < 1) Or (b < 1)) Then 'Operatore 'or'
if Not(a < 1) Then 'Negazione booleana 'not'
if (a = 1) Then 'Uguale (=)
if (a <> 1) Then 'Diverso (<>)
Confronto fra Stringhe
Può apparire strano ma anche il modo di confrontare due stringe pone VB.NET un gradino sopra C#.
In tutti i linguaggi di programmazione, se noi confrontassimo queste due stringhe :
"miastringa" "MiaStringa"
il programma ci direbbe che queste sono diverse. C# e VB.NET si comportano esattamente così.
Visual Basic.NET, nel corso degli anni ha dovuto adattarsi alle richieste degli sviluppatore ed è cresciuto molto. Durante questa evoluzione sono state introdotte molte istruzioni, una delle quali è 'Option Compare'.
Tale istruzione specifica il metodo di confronto delle stringhe, e può essere di tipo binario (Binary) o testuale (Text). Se non è presente 'Option Compare', viene utilizzato Binary come metodo di confronto predefinito.
Se ne deduce che inserendo 'Option Compare Text', il confronto tra le due stringhe precedenti ci dirà che queste sono identiche!
Infatti la modalità di confronto 'Text' prevede questo ordinamento :
(A=a) < ( À=à) < (B=b) < (E=e) < (Ê=ê) < (Z=z) < (Ø=ø)
Mentre 'Binary' :
A < B < E < Z < a < b < e < z < À < Ê < Ø < à < ê < ø
L'opzione 'Option Compare' può essere utilizzata all'interno dei singoli file, ciò fornisce al programmatore una maggiore flessibilità.
L'utile With
Funzionalità presente nel solo Visual Basic.NET, l'istruzione With...End With consente di eseguire una serie di istruzioni su un oggetto specificato senza che sia necessario riqualificare il nome dell'oggetto.
Ad Esempio :
VB.NET
With Label1
.Height = 1000
.Width = 5000
.Text = "Questa è la mia Label"
End With
In questo modo si evita di riscrivere più volte il nome dell'oggetto, rendendo il codice più chiaro e privo di inutili ripetizioni.
La Cortocircuitazione
In C#, utilizzando istruzioni composte viene sempre impiegata una tecnica chiamata 'cortocircuitazione'. Questa consiste nell'eseguire solamente le parti necessarie, tralasciando ciò che è superfluo.
Per maggiore chiarezza, facciamo un esempio :
C#
if ( (a == 1) || (b == 2) )
{
...
}
La condizione valutata è composta da due parti, se la prima parte risultasse vera (a==1) C# NON valuterebbe mai la seconda parte ed eseguirebbe il codice interno al costrutto 'if'.
In Visual Basic.NET :
VB.NET
if ( (a = 1) Or (b = 2) ) then
...
End If
In questo caso, prima vengono valutate entrambe le parti della condizione, e subito dopo viene stabilito se eseguire o meno il codice interno.
Ciò non significa che VB.NET manchi della cortocircuitazione, al contrario permette al programmatore di scegliere quale metodo utilizzare. Infatti troviamo due nuovi operatori, 'AndAlso' e 'OrAlso', che permettono l'uso della tecnica in questione. Quindi, riscrivendo l'esempio :
VB.NET
if ( (a = 1) OrAlso (b = 2) ) then
... End If
L'aggiunta di questi operatori, oltre a consentire una compatibilità con il passato (VB6 e precedenti), permette una maggiore flessibilità rispetto ad altri linguaggi (es.: C#).
Select Case, Intervalli ed Espressioni Multiple
Sia in C# che in Visual Basic.NET è possibile disporre di un'istruzione che gestisce più selezioni trasferendo il controllo a una delle istruzioni 'case' presenti nel corpo.
Sto parlando di 'switch' (C#) e di 'Select Case' (VB.NET). Osserviamo questi esempi :
C#
switch(n)
{
case 1:
a = 1;
break;
case 2:
a = 2;
break;
default:
Console.WriteLine("N non valido.");
break;
}
VB.NET
Select N
Case 1
Console.WriteLine("N = 1")
Case 1 To 5
Console.WriteLine("N compreso fra 2 e 5")
Case 6, 7, 8
Console.WriteLine("N = 6 o 7 o 8")
Case Is > 8
Console.WriteLine("N > 8")
Case Else
Console.WriteLine("N non valido!")
End Select
In C# ogni espressione specificata nell'istruzione 'case' è un semplice valore, al contrario in VB.NET può essere un valore (stringa, intera, ecc..), può essere un intervallo (To), può essere una condizione (Is), addirittura è possibile combinare i vari tipi. Ad Esempio :
VB.NET
Case 1 To 4, 7 To 9, 11, 13, Is > 50
oppure
Case "mela", "a" To "z", ElementoTest
In questo caso Visual Basic.NET dimostra la sua estrema flessibilià, potenza, semplicità e soprattutto chiarezza nelle espressioni. C# invece rimane ancorato alle classiche strutture C/C++/Java senza introdurre alcun miglioramento significativo.
For Each
Entrambe i linguaggi dispongono di un'istruzione per permette di scorrere un'array o un'insieme di oggetti, esaminandone un'elemento alla volta.
In C# troviamo 'Foreach', mentre in VB.NET 'For Each'. Il loro funzionamente è molto simile, l'unica differenza risiede nella capacità di VB.NET di impostare la variabile nella quale, di volta in volta, vengono posti gli elementi analizzati.
Osserviamo questo esempio :
VB.NET
Dim Nazioni(20) As String
Dim NomeNazione As String
For Each NomeNazione In Nazioni
If NomeNazione = "" Then
NomeNazione = "Italia"
End If
System.Console.WriteLine(NomeNazione)
Next NomeNazione
Si osservi che la variabile 'NomeNazione' può essere modificata all'interno del 'For Each', questo senza intaccare i dati presenti nell'array esaminato. Tale interessante caratteristica è assente in C#, che di fatto segnala un errore.
La Gestione dell'Errore
In questo campo VB.NET e C# appaiono, ad una prima analisi, molto simili. Entrambe gestiscono gli errori con i costrutti 'throw', 'try-catch', 'try-finally', 'try-catch-finally'.
Ciò che li distingue e che semplifica la vita agli sviluppatori VB.NET è la presenza, in questo linguaggio, dell'istruzione 'On Error'. Derivata dalle precedenti versioni, 'On Error' consente di attivare una routine di gestione degli errori e di specificarne la posizione all'interno di una routine più ampia, permettendo inoltre di disattivare una routine di gestione degli errori precedentemente attivata.
Chi volesse utilizzare una gestione semplificata dell'errore, troverà in 'On Error' una valida soluzione.
Vista la varietà di usi che si possono fare di 'On Error', per gli esempi si consulti la documentazione ufficiale :
Microsoft MSDN
Le Funzioni
Molte cose ci sarebbero da dire sulle funzioni. VB.NET permette alcuni utilizzi non previsti da C#.
Prima di tutto, con Visual Basic.NET è superfluo indicare il valore ritornato dalle funzioni se questo è nullo ("" per le stringhe, 0 per i numeri, ecc...), infatti se si omette l'istruzione 'return', la funzione restituirà proprio 0, "", ecc... a seconda del tipo di dato.
Ad esempio :
VB.NET
Function TestFx (retA As Boolean) As Integer
Dim a As Integer
If (retA) Then
a = 1
Return a
End If
End Function
In questo caso, la funzione restituirà 0 se 'retA=False', altrimenti ritornerà 1.
L'uso sapiente di questo automatismo consente di minimizzare l'uso dell'istruzione 'Return', rendendo più semplice e scorrevole la lettura del codice, riuscendo a focalizzare l'attenzione sui dati più significativi.
Un'altra particolare caratteristica di Visual Basic.NET è quella di disporre di un sistema alternativo a 'Return'. All'interno delle funzioni è disponibile una variabile che possiede lo stesso nome della funzione, settando la quale, di fatto si imposta il valore da restituire.
Ad esempio, riscrivendo la funzione precedente :
VB.NET
Function TestFx (retA As Boolean) As integer
Dim a As Integer
If (retA) Then
a = 1
TestFx = a
End If
End Function
Per concludere il discorso, non bisogna dimenticare i parametri opzionali. E' infatti possibile definire alcuni parametri come opzionali, ciò permette la loro omissione nella chiamata della funzione.
Ad esempio :
VB.NET
Sub TestFx (par1 As Integer, _
Optional par2 as String = "", _
Optional par3 as Boolean = True)
...
End Sub
In questo esempio 'par2' e 'par3' sono dichiarati opzionali, ciò significa che all'atto della chiamata potremo, a nostra discrezione, indicare o meno i loro valori.
Il modificatore 'Optional', risulta particolarmente utile per semplificare l'uso di funzioni complesse senza dover ricorrere all'overloading. 'Optional' NON è presente in C# ma solo in VB.NET.
I Comandi Visual Basic
Come accade in molti altri linguaggi, Visual Basic.NET possiede una nutrita serie di funzioni, proprietà, metodi, tipi e costanti facenti parte della sua libreria di runtime. Queste, vanno ad aggiungersi alle classi proprie del framework di .NET.
L'uso delle funzioni interne di VB.NET consente, al programmatore, la semplificazione di molte operazione che altrimenti, dovrebbero essere svolte tramite l'uso delle classi del framework.
Per comprendere meglio l'utilità delle funzioni integrate nel runtime di VB.NET osserviamo quanto segue :
VB.NET
'Finestra di messaggio utilizzata attraverso le classi del framework
MessageBox.Show(Me, "Messaggio", "Titolo", MessageBoxButtons.YesNo, _
MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, _
MessageBoxOptions.RightAlign)
'Finestra di messaggio utilizzata attraverso le classi di runtime di VB.NET
MsgBox("Messaggio", vbYesNo Or vbQuestion Or _
vbDefaultButton1 Or vbMsgBoxRight, "Titolo")
Come si può notare l'utilizzo delle funzioni e delle costanti di runtime, semplifica enormemente l'istruzione rendendola molto più chiara ed immediata.
C#, nonostante sia in grado di utilizzare anche le funzioni proprie di VB.NET (in maniera decisamente più macchinosa), non dispone di una propria libreria di runtime.
Using e Imports
In .NET l'organizzazione dei programmi C#, VB, ed in genere qualsiasi altro linguaggio basato su questa piattaforma, si poggia sull'uso degli spazi dei nomi. Questi vengono utilizzati sia come sistema organizzativo "interno" che come sistema organizzativo "esterno", ovvero come un modo per presentare gli elementi del programma esposti ad altri programmi.
Per semplificare l'utilizzo degli spazi dei nomi (namespace) sono disponibili , in VB e C#, le direttive 'imports', per il primo, e 'using' per il secondo.
Così come in altri casi, anche questa volta Visual Basic.NET si pone un gradino sopra C#.
Sia la direttiva 'Using', sia 'Imports' consentono la creazione di un alias per uno spazio dei nomi e l'uso dei tipi in uno spazio dei nomi, evitando di dover qualificare l'uso di un tipo in tale spazio.
Senza queste istruzioni, per utilizzare l'oggetto 'Console' dovremo scrivere così :
C#
System.Console.WriteLine("Messaggio...");
VB.NET
System.Console.WriteLine("Messaggio...")
Al contrario utilizzando 'Using' e 'Imports', semplificheremmo il tutto :
C#
Using System
Console.WriteLine("Messaggio...");
VB.NET
Imports System
Console.WriteLine("Messaggio...")
Con Visual Basic.NET, e la sua 'Imports', possiamo anche fare di meglio. Infatti 'Imports' consente, non solo l'importazione di spazi di nomi ma anche di classi (come ad esempio la classe 'Console'). Questa importante caratteristica ci consente di far riferimento agli elementi di una classe senza doverla specificare.
Riscrivendo l'esempio precedente :
VB.NET
Imports System.Console
WriteLine("Messaggio...")
Questa possibilità, purtroppo, è completamente assente in C#.
I Moduli
In C# l'elemento principale è la Classe. Tutto è racchiuso al suo interno.
VB.NET si spinge oltre, infatti supporta pienamente le Classi (come C#), aggiungendo la possibilità di utilizzare i Moduli.
Questi rappresentano un tipo di riferimento simile alle classi, dalle quali si distinguono però per alcune caratteristiche significative. I loro membri sono, in modo implicito, di tipo 'Shared' (identico allo 'static' di C# )e il loro ambito è limitato allo spazio di dichiarazione dello spazio dei nomi in cui il modulo è dichiarato. A differenza delle classi, i moduli non possono essere instanziati, non supportano l'ereditarietà e non possono implementare interfacce. Un modulo può solamente essere dichiarato in uno spazio dei nomi.
Naturalmente, all'interno dello stesso progetto possono essere presenti più moduli.
Una cosa interessante è che i moduli possono essere esportati, esattamente come le classi, e utilizzati da altri linguaggi.
All'atto pratico un modulo può essere paragonato ad una libreria di variabili, proprietà, eventi, metodi e funzioni in genere.
I Membri Shared
Vengono chiamati metodi condivisi. Sono disponibili sia in C# (usando il modificatore 'Static'), sia in VB.NET (usando il modificatore 'Shared').
Questi metodi non agiscono su una specifica istanza di un tipo e possono essere richiamati direttamente dal tipo anziché attraverso una particolare istanza.
Facciamo un esempio di metodo condiviso :
C#
Class Test
{
private int x;
public static int fxCondivisa()
{
return x;
}
}
Class App
{
public static void Main()
{
int valx;
Test t = New Test();
valx = Test.fxCondivisa();
valx = t.fxCondivisa(); //ERRORE!!!
}
}
VB.NET
Class Test
Private x As Integer
Shared Function fxCondivisa() As Integer
return x
End Function
End Class
Shared Sub Main()
Dim valx As Integer
Dim t As New Test()
valx = Test.fxCondivisa()
valx = t.fxCondivisa()
End Sub
Ciò che VB.NET è in grado di fare, e C# no, è utilizzare i membri 'shared' attraverso l'istanza degli oggetti e non solo attraverso il tipo. Si può in pratica affermare che gli elementi 'shared' sono parte effettiva sia del tipo, sia delle sue istanze.
Avviare i Programmi
Con .NET, l'avvio di un programma avviene attraverso il metodo 'Main'. Indipendentemente dal linguaggio, il metodo 'Main' viene richiamato immediatamente all'avvio del software. Si può dire che 'tutto parte da qui'.
Esistono diversi tipi di dichiarazione per il metodo 'Main', che solitamente risiede all'interno di una Classe. Vediamo un piccolo esempio :
C#
class AppClass
{
public static int Main(string[] args)
{
...
return 0;
}
}
VB.NET
Class AppClass
Function Main(ByVal Args() As String) As Integer
...
return 0;
End Function
End Class
In entrambe i casi, 'Main' si trova all'interno di una classe e riceve, come parametro, l'elenco degli argomenti passati all'eseguibile.
Oltre ai normali utilizzi, Visual Basic.NET aggiungie una interessante caratteristica.
Con VB.NET è possibile evitare l'uso di una classe sostituendola con un semplice modulo :
VB.NET
Module AppMod
Function Main(ByVal Args() As String) As Integer
...
return 0;
End Function
End Module
Questo consente un approccio procedurale alla programmazione, utile soprattutto per piccoli software, dove la struttura generale ha una rilevanza marginale. Comodo per la crezione di semplici librerie di funzioni e intuitivo per il programmatore alle prime armi.
Proprietà
La definizione delle proprietà all'interno delle classi è fondamentale per la gestione degli oggetti. VB.NET e C# consentono un completo controllo su questo importante aspetto.
Come spesso accade, Visual Basic.NET aggiunge una possibilità in più. Con questo linguaggio è infatti possibile definire delle proprietà dotate di parametri. Ad Esempio :
VB.NET
Imports System
Module TestVB
Class clTest
Private strValore As String
Property valore() As String
Get
Return strValore
End Get
Set (ByVal value As String)
strValore = value
End Set
End Property
Property valore(ByVal tipo as string) as string
Get
Return strValore
End Get
Set (ByVal value As string)
strValore = value + " " + tipo
End Set
End Property
End Class
Sub Main()
Dim testObj As New clTest
'proprietà semplice
testObj.valore = "Roberto"
Console.WriteLine(testObj.valore)
'proprietà con parametro
testObj.valore("Rossi") = "Roberto"
Console.WriteLine(testObj.valore)
End Sub
End Module
Alcuni mi hanno fatto notare che questa caratteristica è presente anche in C#. In realtà non è così. C# consente di utilizzare gli indicizzatori. Questi sono membri che consentono di indicizzare un oggetto come se si trattasse di una matrice. In questo caso però si va ad agire su tutto sull'oggetto e non sulla singola proprietà. E' sottointesto che VB.NET possiede anche questa capacità.
Late Binding
Sia C#, sia VB.NET consentono, durante l'esecuzione di un programma di instanziare un'oggetto dinamicamente e indipendentemente dal suo tipo, potendone ricavare ed utilizzare metodi, proprietà ed eventi. Ciò avviene attrave l'utilizzo della tecnica di Riflessione.
In pratica si ha un'oggetto di tipo 'generico' che può essere assegnato ad un tipo X e quindi, è possibile utilizzare metodi, proprieta ed eventi proprio del tipo X.
Vista la complessità dell'argomento, rimando alla documentazione ufficiale ( La Riflessione).
VB.NET possiede la capacità di utilizzare l'associazione tardiva (Late Binding), che in pratica si affianca al sistema di riflessione e semplifica enormemente l'utilizzo dinamico degli oggetti.
Vediamo un esempio :
VB.NET
Imports System
Module TestVB
Class clTest
Private strValore As String
Public Sub SetValore (ByVal dato As String)
strValore = dato
Console.WriteLine(dato)
End Sub
End Class
Sub Main()
Dim testObj As Object 'tipo generico
testObj = New clTest
testObj.SetValore("Esempio...")
End Sub
End Module
Come si può intuire, utilizzare un oggetto di tipo generico (Object), e poi utilizzarlo come se fosse stato convertito in un tipo specifico (clTest), riduce la quantità di codice scritto, rendendo più chiaro e lineare il listato.
Ora applichiamo questa potente funzione di Visual Basic.NET per utilizzare un'istanza di 'Internet Explorer' :
VB.NET
Imports Microsoft.VisualBasic
Module TestVB
Sub Main()
Dim ieObj As Object 'tipo generico
ieObj = CreateObject("InternetExplorer.Application")
ieObj.MenuBar = false
ieObj.Visible = true
ieObj.Navigate("http://rsoftware.altervista.org")
End Sub
End Module
Quest'ultimo utilizzo del 'late binding', associato agli oggetti ActiveX, permette il rapido e semplice riutilizzo di una moltitudine di componenti e applicazione già esistenti (es.: Excel, Word, OpenOffice, AutoCAD ecc...).
Putroppo il 'Late Binding' NON è presente in C#.
Overloading dei Membri nelle Classi
Esistono alcune cose nei linguaggi di programmazioni che mi lasciano molto perplesso.
C#, nuovissimo linguaggio "super moderno", porta con se una triste caratteristica, legata all'ereditarietà.
Osserviamo :
C#
using System;
class AppMain {
public static void Main() {
Derivata objDerivato = new Derivata();
clTest objTest = new clTest();
objDerivato.FunzioneInterna(objTest);
}
}
class clTest
{
//Classe per Test
}
class Principale
{
public virtual void FunzioneInterna (clTest oggetto)
{
Console.WriteLine("Esecuzione FunzioneInterna(clTest) in Classe Principale");
}
}
class Derivata : Principale
{
public override void FunzioneInterna (clTest oggetto)
{
Console.WriteLine("Esecuzione FunzioneInterna(clTest) in Classe Derivata");
}
public void FunzioneInterna (object oggetto)
{
Console.WriteLine("Esecuzione FunzioneInterna(object) in Classe Derivata");
}
}
Il risultato prodotto al prompt dei comandi :
Esecuzione FunzioneInterna(object) in Classe Derivata
Esaminando il codice si vede, charamente, che l'oggetto objTest (di tipo clTest), passato al metodo FunzioneInterna della classe Derivata, esegue "FunzioneInterna(object oggetto)". La cosa strana è che, all'interno della classe Derivata è presente un'altro metodo FunzioneInterna che accetta esattamente il tipo di dato di objTest (tipo clTest). Perchè non viene richiamato questo metodo, visto che è decisamente più compatibile con il dato passato ? Ma?!?! Non mi capacito.
Evidentemente C# porta con se l'eredità di C++ che funziona esattamente allo stesso modo.
Visual Basic.NET al contrario, si comporta esattamente come vorrebbe la logica. Osserviamo lo stesso esempio :
VB.NET
Imports System
Module TestVB
Sub Main()
Dim objDerivato As New Derivata
Dim objTest As New clTest
objDerivato.FunzioneInterna(objTest)
End Sub
End Module
Class clTest
'Classe per Test
End Class
Class Principale
Public Overridable Sub FunzioneInterna(oggetto As clTest)
Console.WriteLine("Esecuzione FunzioneInterna(clTest) in Classe Principale")
End Sub
End Class
Class Derivata : Inherits Principale
Public Overloads Overrides Sub FunzioneInterna (oggetto As clTest)
Console.WriteLine("Esecuzione FunzioneInterna(clTest) in Classe Derivata")
End Sub
Public Overloads Sub FunzioneInterna (oggetto As Object)
Console.WriteLine("Esecuzione FunzioneInterna(object) in Classe Derivata")
End Sub
End Class
Il risultato prodotto al prompt dei comandi :
Esecuzione FunzioneInterna(clTest) in Classe Derivata
Logicamente, passando l'oggetto objTest (tipo clTest) al metodo FunzioneInterna presente nella classe Derivata, viene richiamato il metodo più compatibile con il tipo di dato utilizzato.
Considerazioni Finali
Per concludere, ecco la fatidica domanda. Usare Visual Basic.NET o C#?
Secondo il mio parere, dipende da quali conoscenze di base si hanno e da quali progetti si vogliono realizzare.
Se non si hanno esperienze di programmazione, la strada migliore è quella di VB.NET. Più intuitivo e semplice, può sfruttare completamente le funzionalità di .NET.
Se si proviene da vecchie versioni di Visual Basic, e non si vuole perdere tempo per nulla, la scelta più sensata è VB.NET.
Se si programma in Java, passando a C# si semplifica la migrazione, avendo quest'ultimo una sintassi in stile C++.
Conoscendo C/C++ la questione è più complessa. Da un lato la migrazione a C# sarebbe più semplice, però bisogna considerare che C++ consente l'utilizzo del Framework .NET senza bisogno di cambiare linguaggio. Ciò, dal mio punto di vista, significa che chi sviluppa con C++ avrebbe maggiori vantaggi a continuare su questa strada aggiungendo le conoscenze sulle librerie .NET. Inoltre non dimentichiamoci che, comunque, l'uso di C/C++ è ancora indispensabile in una moltitudine di casi, soprattutto quando si vogliono realizzare applicazioni particolarmente pesanti (es.: software di CAD), magari da far girare du PC non molto potenti, o più semplicemente se si desidera integrare particolari procedure (Es.: codice assembler). Si tenga anche presente che C/C++ è l'unico linguaggio a poter compilare i software senza la necessita di installare il Framework.NET.
Per gli utilizzatori di altri linguaggi (es.: Delphi, Lisp, ecc...), soprattutto quelli che non possiedono una sintassi simile a C/C++, e che desiderano sviluppare con i prodotti Microsoft, VB.NET rappresenta la scelta più azzeccata, sufficientemente semplice, descrittivo, chiaro e con tutta la potenza di .NET.
Se si desidera sviluppare software per Linux, la scelta attualmente appare obbligata, C#. I due progetti principali di porting di .NET su Linux, comprendono solo compilatori C# e C. Nello specifico sto parlando di :
Mono
DotGNU
Bisogna però dire che sono già in preparazione compilatori Visual Basic.NET anche per questi progetti. Ad esempio, il progetto Mono prevede l'introduzione del compilatore VB.NET già nell'anno in corso (2005).
Infine parliamo di prestazioni. Questa volta Microsoft ha detto il vero. A parità di funzioni utilizzate, che il software venga sviluppato con Visual Basic.NET o C#, le prestazioni non cambiano di una 'virgola'.
Chi volesse fornire il suo contributo con, critiche, suggerimenti, aggiunte, segnalazioni di errore, ecc... può farlo cliccando qui.
Copyright e autorizzazione:
Copyright 2005-2009 Roberto Rossi
Web : http://www.redchar.net
La copia di questo articolo e la sua distribuzione sono permessi in qualsiasi forma senza il pagamento di diritti di autore a patto che l'indicazione del copyright e questa indicazione siano riportate.