Stan Schultes
Microsoft MVP
Ottobre 2004
Riassunto: Questo articolo esamina i numerosi nuovi miglioramenti che sono stati introdotti in Visual Basic 2005 proponendo semplici esempi di codice che ne illustrano il funzionamento. Le funzionalità trattate comprendono i commenti XML, insiemi generici, parola chiave Global, tipi parziali, My e altro (20 pagine stampate).
Nota Questo articolo e gli esempi di codice sono basati su una versione preliminare di Microsoft Visual Studio 2005, nota in precedenza con il nome in codice "Whidbey". Tutte le informazioni qui contenute sono soggette a modifica.
Introduzione
My
Commenti XML
Insiemi generici
Istruzione Using
Istruzione Continue
Parola chiave Global
Operatore IsNot
Istruzione TryCast
Overload degli operatori e
operatori di conversione
Accessibilità delle funzioni
di accesso alle proprietà
Funzioni di accesso agli
eventi personalizzate
Tipi parziali
Eventi a livello di
applicazione
Tipi unsigned (senza segno)
Istanze predefinite
Avvisi del compilatore
Limiti di matrice espliciti
Conclusioni
La versione Public Beta di Visual Studio 2005 fornisce un'anteprima stabile di Visual Basic 2005 nella quale le nuove funzionalità sono state consolidate al punto che i cambiamenti rispetto alla versione finale dovrebbero essere minimi. Ovviamente, alcune cose subiranno certamente delle modifiche, ma è prevedibile che il prodotto finale sia molto simile all'anteprima Beta 1. Ciò nonostante, il consiglio è di non installare la versione Beta su un computer di produzione e di operare invece nel contesto di sicurezza di un'immagine di Microsoft Virtual PC.
Le modifiche principali apportate al linguaggio Visual Basic comprendono My, i commenti XML e gli insiemi generici. Alcune nuove istruzioni del linguaggio colmano alcune lacune logiche e comprendono Using, Continue e TryCast nonché la parola chiave Global. Vi sono vari miglioramenti strutturali che comprendono modifiche dell'accessibilità alle funzioni di accesso delle proprietà, funzioni di accesso agli eventi personalizzate, tipi parziali ed eventi a livello di applicazione. L'overload degli operatori e gli operatori di conversione, nonché l'operatore IsNot costituiscono delle novità. Altre utili modifiche comprendono i tipi unsigned (senza segno), le istanze predefinite dei form, gli avvisi del compilatore e i limiti di matrice espliciti.
Al primo avvio di Visual Studio 2005 viene richiesto di selezionare le impostazioni IDE preferite. Queste impostazioni controllano funzionalità quali il mapping dei tasti dell'IDE, i layout della finestra e la formattazione del codice nell'editor. È possibile modificare le impostazioni in qualsiasi momento mediante la voce di menu Tools | Import/Export Settings come mostrato nella figura 1. È anche possibile importare impostazioni predefinite per un altro linguaggio di programmazione oppure importare file con impostazioni personalizzate che vengono utilizzati da tutti gli sviluppatori in una società.

Figura 1. Importazione di impostazioni personalizzate per standardizzare l'ambiente di sviluppo aziendale
Una delle maggiori difficoltà per gli sviluppatori nella migrazione a .NET da Visual Basic 6.0 e versioni precedenti è l'elevata dimensione di .NET Framework e del numero di classi nella relativa gerarchia dello spazio dei nomi. Gli oggetti applicazione e ambiente di utilizzo comune si trovano ovunque nella BCL (Base Class Library) di .NET Framework, e l'apprendimento delle relative posizioni richiede del tempo. La nuova gerarchia My in Visual Basic 2005 accelera e semplifica lo sviluppo di applicazioni fornendo un accesso pratico e organizzato in modo logico a molte classi framework di utilizzo comune.
My è disponibile in due formati:
I collegamenti My costituiscono sostanzialmente un metodo di accesso diretto a molti oggetti BCL di utilizzo comune. I collegamenti My di livello superiore sono My.Application, My.Computer e My.User, ciascuno dei quali contiene la propria gerarchia di oggetti. Ad esempio, l'oggetto My.User espone Audio, FileSystem, Keyboard, Mouse, Network, Registry e altri:
Dim sVar As String sVar = My.User.Identity.Name sVar = My.Computer.Info.OSFullName sVar = My.Application.CommandLineArgs.Count.ToString
Gli oggetti My dinamici vengono compilati automaticamente da Visual Basic quando si aggiungono form, risorse, impostazioni e servizi Web al progetto. My.Resources e My.Settings sono di particolare interesse, in quanto il compilatore Visual Basic genera riferimenti di variabili tipizzate in modo sicuro quando si aggiungono risorse e impostazioni al progetto.
Fare doppio clic sulla voce My Project in Esplora soluzioni per richiamare progettazione applicazione. Fare clic su Settings nell'elenco delle schede sul lato sinistro come mostrato nella figura 2.

Figura 2. Progettazione applicazione con la scheda Settings. Il riquadro Error List mostra errori, avvisi e messaggi e ora è separato da Elenco attività.
Aggiungere un nome di impostazione come MaxInputValue del tipo Integer nell'ambito User con un valore di 100. È possibile fare subito riferimento nel codice a questa impostazione tramite un oggetto tipizzato in modo sicuro con IntelliSense completo come mostrato nella figura 3.

Figura 3. Esempio di popup IntelliSense per un valore di impostazioni creato nella progettazione applicazione Settings
Nell'angolo superiore destro della progettazione Settings è presente un collegamento etichettatoView Code. Fare clic su tale collegamento per visualizzare il file di nome MySettings_user.vb. Il file è una classe parziale nella quale è possibile aggiungere codice per gestire gli eventi di impostazioni per aggiornare lo stato dell'applicazione quando le impostazioni vengono cambiate (per ulteriori informazioni, vedere la sezione Tipi parziali):
Partial Public Class MySettings
'...
End Class
Qui vengono esposti tre eventi MySettings:
L'interfaccia Settings dell'applicazione è innestabile, vale a dire che l'implementazione di queste routine di eventi consente di definire in che modo devono essere salvate le impostazioni.
Lo stesso tipo di tipizzazione sicura si ottiene quando vengono aggiunte risorse (Resources) al progetto. Se si rilascia un'immagine di nome Happy.bmp nell'area Images della progettazione Resources, è possibile farvi riferimento nel codice come My.Resources.Happy. Happy è di tipo Bitmap, e ciò significa che non è necessario descrivere un tipo Object o Image per utilizzare la bitmap nel codice. IntelliSense funziona immediatamente anche quando si digita Happy nel codice. Ad esempio:
PictureBox1.Image = My.Resources.HAPPY
Questa riga di codice assegna l'oggetto bitmap alla proprietà Image di PictureBox. Nella figura 4 è possibile vedere la finestra a comparsa IntelliSense, indicante che l'oggetto è di tipo Bitmap.

Figura 4. Il trascinamento di un'immagine bitmap sulla scheda Resources in progettazione applicazione determina un oggetto tipizzato in modo sicuro che è possibile utilizzare immediatamente nel codice.
Mano a mano che vengono aggiunti form e servizi Web al progetto, l'oggetto My viene popolato dinamicamente tramite istanze predefinite di questi oggetti tipizzati in modo sicuro ai quali è possibile fare riferimento nel codice.
Come si può vedere, My rende più pratica l'individuazione delle classi BCL correlate all'applicazione e all'ambiente e fornisce l'accesso immediato e tipizzato in modo sicuro a impostazioni, risorse e altri aggetti da aggiungere ai progetti. Questi costituiscono importanti miglioramenti della produttività per gli sviluppatori Visual Basic di qualsiasi livello di esperienza.
I commenti XML consentono di aggiungere documentazione strutturata al codice e hanno costituito motivo di invidia per gli sviluppatori Visual Basic perché nel linguaggio C# erano già disponibili da tempo. I commenti XML possono descrivere vari elementi del codice, tra cui classi, campi, metodi ed enumerazioni.
Dopo avere creato un commento XML che descrive una funzionalità del codice, quando si digita quest'ultima nell'editor viene attivato immediatamente IntelliSense con i parametri e il tipo restituito. Supponiamo di avere un prototipo di funzione con la seguente firma:
Private Function GetCustomerData(ByVal CustomerCode As String) _
As DataSet
Posizionare il punto di inserimento nel codice sulla riga precedente alla dichiarazione di funzione e digitare tre caratteri virgoletta singola. Visual Basic genera un modello di commento XML corrispondente alla dichiarazione di funzione che può essere selezionato tramite tabulazione e compilato come un modulo. Supponiamo di compilare il modello di commento della funzione nel modo seguente:
''' <summary> ''' Returns a DataSet for a single customer. ''' </summary> ''' <param name="CustomerCode">Customer Code as String.</param> ''' <returns>DataSet for the supplied CustomerCode.</returns> ''' <remarks>Resides in the application's data layer.</remarks>
Quando si digita questo nome di funzione in un altro punto del codice, verrà fornito il supporto IntelliSense completo con riepilogo della funzione, parametri e valore restituito, come mostrato nella figura 5.

Figura 5. Questa descrizione comando mostra il suggerimento IntelliSense immediato che si ottiene quando vengono aggiunti commenti XML agli elementi del codice.
Questa funzione è un elemento chiave negli ambienti aziendali e in team. È possibile generare documentazione del codice da commenti XML strutturati inseriti nei file sorgente. Inoltre, un architetto di applicazioni o uno sviluppatore leader è in grado di prototipizzare e commentare le funzionalità prima dell'implementazione. Quando gli sviluppatori scrivono il codice mediante gli oggetti prototipo, IntelliSense fornisce la guida all'utilizzo appropriato delle funzionalità.
I commenti XML vengono trattati dal compilatore come parte integrale del codice. I valori di tag dei commenti sono colorati come commenti e se si comprime la struttura di un commento XML viene visualizzato il valore del tag di riepilogo invece dell'intero modello di commento XML (vedere la figura 6).

Figure 6. I commenti XML sono pienamente integrati con il compilatore e la finestra del codice. Il commento XML nella funzione FillDataGrid è compresso fino alla relativa riga di riepilogo.
Se si modifica il nome del parametro CustomerCode nel prototipo di
funzione in CustomerID, il compilatore aggiunge una linea verde ondulata
sotto il tag <param name="CustomerCode"> per
avvisare che i due nomi non corrispondono (per ulteriori informazioni, vedere
la sezioneAvvisi del
compilatore).
Quando si genera il progetto, Visual Basic crea automaticamente un file di documentazione XML. Questo file appare nella directory di output dell'applicazione con il nome AssemblyName.xml. Trattandosi di un file XML, è possibile trasformarlo facilmente in un altro formato di output a seconda delle esigenze. I commenti XML semplificano e rendono notevolmente più pratica la generazione della documentazione del codice, sia in termini di supporto IntelliSense durante la scrittura del codice, sia in termini di documentazione del codice dopo avere generato l'applicazione.
La BCL ora fornisce lo spazio dei nomi System.Collections.Generic, che contiene varie classi che definiscono insiemi generici. Vengono definiti generici perché al momento della dichiarazione si specifica un segnaposto di tipo per gli oggetti contenuti invece di un tipo specifico. Agli oggetti memorizzati viene assegnato un tipo specifico sono quando si crea un'istanza dell'insieme.
Gli insiemi generici consentono di ottenere notevoli risparmi di tempo. Chiunque abbia creato insiemi personalizzati conosce la quantità di codice che può essere necessaria. Gli insiemi generici in Visual Basic consentono di creare in una riga di codice l'equivalente di un insieme personalizzato. Non è più necessario creare insiemi personalizzati separati per ciascun tipo di oggetto da memorizzare. È sufficiente fornire il tipo desiderato nel momento in cui viene creata l'istanza dell'insieme generico.
Il modo più semplice per vedere come funzionano gli insiemi generici è tramite un esempio. Supponiamo di avere una semplice classe Customer con due proprietà pubbliche, mostrate come variabili pubbliche per brevità:
Public Class Customer
Public Name As String
Public CreditLimit As Decimal
Public Sub New(ByVal CustomerName As String, _
ByVal CustCreditLimit As Decimal)
Name = CustomerName
CreditLimit = CustCreditLimit
End Sub
End Class
È possibile dichiarare un elenco di Customers mediante la classe List dell'insieme generico nel modo seguente:
Dim Customers As New System.Collections.Generic.List(Of Customer)
Tramite questa singola riga di codice è stato dichiarato un elenco tipizzato in modo sicuro che memorizza solo i tipi Customer e fornisce completo supporto IntelliSense sugli oggetti Customer contenuti. In modo analogo è possibile creare facilmente un elenco di oggetti Product o Order, creando di fatto un set di insiemi personalizzati senza la necessità di scrivere tutto il codice dell'insieme personalizzato per ciascun tipo. Ora è possibile scrivere del codice come il seguente:
Dim custA As New Customer("CustA", 1000)
Customers.Add(custA)
Dim custB As New Customer("CustB", 2000)
Customers.Add(custB)
For Each c As Customer In Customers
MessageBox.Show("Customer: " & c.Name & _
", limit: " & c.CreditLimit)
Next
'compile error: Product cannot be converted to Customer
Dim prodA As New Product("ProdA", CDec(29.95))
Customers.Add(prodA)
L'utilizzo di insiemi generici offre anche vantaggi in termini di prestazioni in quanto gli oggetti memorizzati sono tipizzati in modo sicuro e non vengono conservati internamente come oggetti del tipo.
Nello spazio dei nomi System.Collections.Generic sono disponibili altri insiemi generici. Ad esempio, l'insieme Dictionary(di K,V) consente di specificare tipi per i tasti e i valori. Gli insiemi generici LinkedList(di T) e Stack(di T) si comportano come normali elenchi e stack collegati, fatta eccezione per il fatto che è possibile specificare quali tipi di oggetti vi saranno contenuti.
È possibile creare propri tipi generici utilizzando la nuova sintassi di dichiarazione del tipo generico. Consideriamo una classe Comparer che consente di confrontare differenti tipi di oggetti:
Public Class Comparer(Of itemType)
'...
End Class
È possibile definire diversi segnaposto del tipo in un elenco separato da virgola. È anche possibile definire vincoli che limitano le classi che possono essere fornite all'istanza creata dell'insieme generico:
Public Class Comparer(Of itemType As IComparable)
'...
End Class
Questo vincolo assicura che le istanze Comparer(di T) possono essere create solo tramite classi che implementano l'interfaccia IComparable. Anche alla dichiarazione della classe è possibile applicare diversi vincoli.
A titolo di esempio, consideriamo una classe Customers espansa che implementa IComparable:
Public Class Customer
Implements IComparable
Public Name As String
Public CreditLimit As Decimal
Public Sub New(ByVal CustomerName As String, _
ByVal CustCreditLimit As Decimal)
Name = CustomerName
CreditLimit = CustCreditLimit
End Sub
Public Function CompareTo(ByVal obj As Object) As Integer _
Implements IComparable.CompareTo
Dim c As Customer = CType(obj, Customer)
If CreditLimit > c.CreditLimit Then Return 1
If CreditLimit < c.CreditLimit Then Return -1
Return 0
End Function
End Class
Viene implementata una classe Product simile, tranne che la funzione CompareTo confronta i prezzi dei prodotti invece dei limiti di credito dei clienti:
Public Class Product
Implements IComparable
Public Name As String
Public Price As Decimal
Public Sub New(...)...
Public Function CompareTo(...)...
End Class
Ora la classe Comparer fornisce il funzionamento del confronto generico:
Public Class Comparer(Of itemType As IComparable)
Public Function GetLargest(ByVal Item1 As itemType, _
ByVal Item2 As itemType) As itemType
Dim i As Integer = Item1.CompareTo(Item2)
If i > 0 Then Return Item1
If i < 0 Then Return Item2
Return Nothing
End Function
End Class
È possibile creare un'istanza di Comparers con oggetti di tipi differenti:
Dim pc As New Comparer(Of Product)
Dim prod1 As New Product("LittleOne", 10)
Dim prod2 As New Product("BigOne", 100)
Dim lp As Product = pc.GetLargest(prod1, prod2)
MessageBox.Show("The more expensive product is: " & lp.Name)
Dim cc As New Comparer(Of Customer)
Dim cust1 As New Customer("SmallCo", 1000)
Dim cust2 As New Customer("LargeCo", 5000)
Dim lc As Customer = cc.GetLargest(cust1, cust2)
MessageBox.Show("The customer with a higher limit is: " & lc.Name)
Senza gli insiemi generici, sarebbe necessario definire una classe di confronto per ciascun tipo di oggetto da confrontare, ad esempio, ProductComparer e OrderComparer.
Gli insiemi generici possono ridurre in modo significativo il lavoro di scrittura del codice in numerose situazioni comuni. Considerare il loro utilizzo in presenza di diverse classi che variano solo per il tipo di oggetto su cui operano.
L'istruzione Using rappresenta una scorciatoia per acquisire un oggetto, eseguire del codice tramite di esso e rilasciarlo immediatamente. Vari oggetti framework come grafici, gestori di file, porte di comunicazione e connessioni SQL richiedono che vengano rilasciati gli oggetti che si creano per evitare perdite di memoria nelle applicazioni. Supponiamo di voler disegnare un rettangolo utilizzando un oggetto pennello (brush):
Using g As Graphics = Me.CreateGraphics()
Using br As System.Drawing.SolidBrush = _
New SolidBrush(System.Drawing.Color.Blue)
g.FillRectangle(br, New Rectangle(30, 50, 230, 200))
End Using
End Using
Dopo averli utilizzati è opportuno sbarazzarsi degli oggetti grafico e pennello, e l'istruzione Using semplifica notevolmente l'operazione. L'istruzione Using è molto più chiara rispetto all'utilizzo di Try / Catch e al rilascio dell'oggetto nel blocco Finally come accade in Visual Basic .NET.
L'istruzione Continue ignora la successiva iterazione di un ciclo, rendendo la logica del ciclo più concisa e di facile lettura:
Dim j As Integer
Dim prod As Integer
For i As Integer = 0 To 100
j = 0
While j < i
prod = i * j
If prod > 5000 Then
'skips to the next For value
Continue For
End If
j += 1
End While
Next
L'istruzione Continue è molto pulita e semplifica alquanto l'uscita dal ciclo più interno senza la necessità di ricorrere a un'etichetta e a un'istruzione goto. L'istruzione Continue opera sui cicli For, While e Do.
La parola chiave Global rende accessibile lo spazio dei nomi di primo livello, o vuoto, in cima alla gerarchia degli spazi dei nomi. In passato, non era possibile definire uno spazio de nomi System.IO all'interno della gerarchia degli spazi dei nomi della società:
Namespace MyCompany.System.IO
Ciò avrebbe danneggiato tutti i riferimenti allo spazio dei nomi System di framework all'interno dell'applicazione. Ora è possibile utilizzare la parola chiave Global per eliminare le ambiguità negli spazi dei nomi:
Dim myFile As Global.System.IO.File
La parola chiave Global è particolarmente utile negli scenari di generazione del codice in cui si desidera garantire la certezza assoluta che i riferimenti allo spazio dei nomi generato sia esattamente come previsto. È prevedibile che lo stesso Visual Basic ricorrerà all'utilizzo della parola chiave Global in tutto il codice generato.
L'operatore IsNot fornisce una controparte dell'operatore Is. Invece del complicato e spesso utilizzato controllo della presenza di un'istanza di un oggetto prima di farvi riferimento:
If Not myObj Is Nothing Then
IsNot consente di utilizzare un confronto diretto eliminando l'operatore Not:
If myObj IsNot Nothing Then
Analogamente, è possibile eliminare l'operatore Not quando si controlla se due istanze di oggetti sono differenti:
If MyObj1 IsNot MyObj2 Then
Pur essendo un'innovazione semplice, IsNot colma una lacuna di coerenza nel linguaggio Visual Basic che contribuisce a rendere più chiaro il codice.
In Visual Basic 2003, è possibile convertire un tipo di oggetto in un altro tipo in uno di due modi:
Dim p As Product p = CType(obj, Product) p = DirectCast(obj, Product)
Qui, è possibile utilizzare CType per convertire da un tipo a un altro,
mentre DirectCast richiede che vi sia una relazione di ereditarietà o di
implementazione tra gli oggetti. Il problema in questi casi è che verrà
generata un'eccezione in fase di esecuzione se obj non
può essere convertito o non può esser associato al tipo Product.
Immettere la nuova istruzione TryCast. L'utilizzo è analogo a CType
o DirectCast, tranne che il risultato restituito è Nothing
se l'operazione non può essere completata:
p = TryCast(obj, Product)
If p IsNot Nothing Then
'use the p object...
End If
Una delle più potenti innovazioni introdotte in Visual Basic 2005 è l'overload degli operatori. L'overload degli operatori consente di definire operatori che agiscono su qualsiasi tipo desiderato, anche fino al punto di creare specifici tipi di base.
Il classico esempio di overload dell'operatore è l'aggiunta di numeri complessi. Una classe Complex semplificata con l'overload dell'operatore + potrebbe essere simile alla seguente:
Public Class Complex
Public Real As Double
Public Imag As Double
Public Sub New(ByVal realPart As Double, ByVal imagPart As Double)
Real = realPart
Imag = imagPart
End Sub
Shared Operator +(ByVal lhs As Complex, ByVal rhs As Complex) _
As Complex
Return New Complex(lhs.Real + rhs.Real, lhs.Imag + rhs.Imag)
End Operator
End Class
Utilizzare l'operatore + per sommare numeri complessi in modo alquanto intuitivo:
Dim lhs As Complex = New Complex(2.0, 2.5) Dim rhs As Complex = New Complex(3.0, 3.5) Dim res As Complex = lhs + rhs 'res.real = 5.0, res.imag = 6.0
È anche possibile eseguire l'overload degli operatori di conversione per i tipi
personalizzati. Se si tenta di convertire il valore di res
come CType(res,String), verrà generato un errore del compilatore "Complex
cannot be converted to String". Se si cerca di
consultare il valore di Res.ToString si ottiene di
ritorno un valore Complex in quanto ToString mostra
per impostazione predefinita il nome del tipo. Questi problemi possono essere
risolti tramite l'overload dell'operatore di conversione CType e del
metodo ToString nel modo seguente:
Public Shared Narrowing Operator CType(ByVal Value As Complex) _
As String
Return Value.Real.ToString & "i" & Value.Imag.ToString
End Operator
Public Overrides Function ToString(ByVal Value As Complex) As String
Return Value.Real.ToString & "i" & Value.Imag.ToString
End Function
Ora i valori restituiti di CType(res,String) e res.ToString
sono come previsto: "5.0i6.0". Gli operatori di conversione devono essere
dichiarati con Narrowing o Widening, indicando in che modo deve essere eseguita
la conversione.
Un problema che ha sempre costituito fonte di preoccupazione relativamente alle proprietà di Visual Basic .NET è che le funzioni di accesso Get e Set devono sempre avere lo stesso livello di accesso (Public, Friend o Private). Se si desidera creare una proprietà pubblica di sola lettura (solo Get è pubblica), non esiste alcuna funzione di accesso Set che è possibile utilizzare all'interno del componente per imporre la convalida o la gestione personalizzata della proprietà.
Le funzioni di accesso Get e Set in Visual Basic 2005 ora sono in grado di avere differenti impostazioni di accessibilità, a condizione che Set sia più restrittiva di Get:
Private _myProp As String
Public Property MyProp() As String
Get
Return _myProp
End Get
Friend Set(ByVal value As String)
If value.Trim.Length > 0 Then
_myProp = value.Trim
Else
value = "<no value>"
End If
End Set
End Property
Questo è particolarmente utile negli ambienti di sviluppo in team e per gli sviluppatori individuali che si sforzano di ottenere la massima quantità di riutilizzo del codice.
Le funzioni di accesso agli eventi consentono di definire un evento personalizzato e di controllare che cosa accade quando i client aggiungono e rimuovono gestori e generano l'evento. Supponiamo di avere una classe personalizzata in cui viene generato un evento RateChanged. Gli eventi normali vengono dichiarati in uno dei due modi seguenti:
Public Event RateChanged() 'or Public Event HoursChanged As EventHandler
Gli eventi dichiarati in questo modo hanno un archivio di backup gestito automaticamente. In altre parole, il sistema gestisce il modo in cui gli eventi vengono gestiti e smistati. In genere questo funziona correttamente, ma in alcuni casi è necessario un maggiore controllo sul modo in cui i listener dell'evento vengono notificati.
Un evento personalizzato e i relativi accessori vengono dichiarati utilizzando la nuova parola chiave Custom. Quando si preme il tasto Invio sulla dichiarazione di evento, Visual Basic 2005 crea automaticamente il prototipo di codice nello stesso modo in cui vengono generate le funzioni di accesso Property:
Public Custom Event NameChanged As EventHandler
AddHandler(ByVal value As EventHandler)
'hook handler to backing store
End AddHandler
RemoveHandler(ByVal value As EventHandler)
'remove handler from backing store
End RemoveHandler
RaiseEvent(ByVal sender As Object, ByVal e As EventArgs)
'invoke listeners
End RaiseEvent
End Event
Quando il client aggiunge o rimuove un gestore per l'evento viene eseguita la routine AddHandler o RemoveHandler. Quando l'evento viene generato, la routine RaiseEvent viene eseguita. In questo modo, è possibile intraprendere azioni specifiche basate sul modo in cui si desidera gestire l'archivio di backup dell'evento. Quando si creano eventi personalizzati in questo modo è possibile considerare l'evento come se fosse una proprietà.
Un esempio in cui questo si può rivelare utile è quando l'oggetto è serializzabile ed è presente un evento che viene gestito da un oggetto delegato non serializzabile. Se si tenta di serializzare l'oggetto tramite un evento normale, l'operazione non riuscirà perché l'archiviazione che supporta l'evento non è serializzabile. Rocky Lhotka, un altro Visual Basic MVP, offre una spiegazione di questo concetto e un esempio dettagliato nel suo blog all'indirizzo http://www.lhotka.net/WeBlog/CommentView.aspx?guid=776f44e8-aaec-4845-b649-e0d840e6de2c.
I tipi parziali consentono di definire un tipo singolo attraverso più file sorgente. La definizione del tipo ha una normale dichiarazione in un file:
Public Class TestPartial
'implementation...
End Class
Negli altri file sorgente viene utilizzata la parola chiave Partial per indicare al compilatore che il codice è una continuazione della definizione della classe originale:
Partial Public Class TestPartial
'implementation...
End Class
Il codice nelle classi generate dagli ambienti di progettazione nell'IDE sono contrassegnati con la parola chiave Partial e sono sperati dal codice utente. Aggiungere un form di nome TestForm a un progetto e osservare il file sorgente risultante. Può sorprendere vedere che è vuoto fatta eccezione per la dichiarazione di classe del form. Dov'è quindi tutto il codice generato dalla progettazione che viene utilizzato per accedere all'interno dell'area del Codice generato da Progettazione Windows Form?
Il codice generato dalla progettazione è ora inserito nel file TestForm.designer.vb, che è possibile visualizzare facendo clic sul pulsante Mostra tutti i file nella barra degli strumenti Esplora soluzioni. Il codice di questo file non deve essere modificato, ma è possibile copiare e incollare le parti necessarie nel file TestForm.vb file se si desidera preservare qualcosa quando il file della progettazione viene rigenerato successivamente.
I team di progetto possono sfruttare i vantaggi delle classi parziali fornendo a ciascuno sviluppatore un file contenente la relativa porzione della classe. Più sviluppatori non hanno più l'esigenza di condividere l'accesso agli stessi file sorgente in quanto ora è possibile separare la definizione di una classe in più file.
Un'altra nuova funzionalità da sfruttare è costituita da una nuova serie di eventi a livello di applicazione disponibili in una classe parziale di nome MyApplication. Cercare un file di nome MyEvents.vb sotto la voce My Project in Esplora soluzioni. È anche possibile trovare questo file dietro il pulsante Visualizza codice nella scheda Applicazione in progettazione applicazione.
Questi nuovi eventi a livello di applicazione sono simili agli eventi dell'applicazione nel file global.asax file in un'applicazione ASP.NET. Vengono esposti cinque eventi:
I primi tre eventi vengono attivati all'avvio e all'arresto dell'applicazione. NetworkAvailabilityChanged viene attivato quando nel computer viene modificato lo stato della rete. Inserire del codice nell'evento UnhandledException nel caso venga generata un'eccezione che non viene gestita altrove.
Visual Basic 2005 offre il supporto completo dei tipi unsigned. I nomi dei tipi unsigned sono:
I tipi unsigned funzionano come tipi normali tranne che sono in grado di memorizzare solo interi positivi.
I tipi unsigned sono estremamente utili in Visual Basic per eseguire chiamate alle API Win32 che prendono come parametri tipi unsigned. Il codice seguente illustra una chiamata alla API MessageBox di Windows:
Public Enum WindowsMessageResult As UInteger
OK = 1
Cancel = 8
End Enum
Private Const MB_OK As UInteger = 0
Private Const MB_ICONEXCLAMATION As UInteger = &H30
Private Const MB_OPTIONS As UInteger = MB_OK Or MB_ICONEXCLAMATION
Private Declare Auto Function Win_MB Lib _
"user32.dll" Alias "MessageBox" _
(ByVal hWnd As Integer, ByVal lpText As String, _
ByVal lpCaption As String, ByVal uType As UInteger) _
As UInteger
Public Function MessageThroughWindows(ByVal message As String, _
ByVal caption As String) As WindowsMessageResult
Dim r As UInteger = Win_MB(0, message, caption, MB_OPTIONS)
Return CType(r, WindowsMessageResult)
End Function
Notare che l'ultimo parametro e il tipo restituito nella dichiarazione Win_MB sono entrambi tipi UInteger.
I tipi unsigned sono di aiuto anche per risparmiare memoria se è necessario memorizzare valori più grandi di un Integer. Il tipo Integer utilizza quattro byte di memoria e può memorizzare valori positivi e negativi fino a 2.147.483.648. Anche il tipo UInteger utilizza quattro byte ed è in grado di memorizzare un valore tra zero e 4.294.967.295. In assenza di un tipo unsigned sarebbe necessario utilizzare un tipo Long che richiede otto byte di memoria per memorizzare valori così grandi.
Un altro cambiamento introdotto in Visual Basic .NET che ha indotto numerosi sviluppatori alla migrazione da Visual Basic 6.0 è la mancanza di un'istanza predefinita per i form. È necessario creare un'istanza del form prima di utilizzarlo:
Dim frm As New Form2 frm.Show()
Visual Basic 2005 supporta le istanze predefinite dei form, così è possibile utilizzare la seguente sintassi familiare:
Form2.Show()
La cosa migliore è accedere a questa istanza di form predefinita attraverso l'insieme My.Forms:
My.Forms.Form2.Show()
Visual Basic 2005 supporta gli avvisi del compilatore, che forniscono una visione dei problemi che si possono verificare in fase di esecuzione. Un avviso viene mostrato sotto forma di una linea verde ondulata nel codice, mentre gli errori sono di colore blu.
Gli avvisi del compilatore comprendono l'accesso ricorsivo alle proprietà, la sovrapposizione di blocchi catch o di istruzioni case, la creazione di una funzione senza un valore di ritorno, e altri. Il mio avviso preferito è per un riferimento di variabile a un oggetto non inizializzato:
Dim cust As Customer If cust.Name.Length = 0 Then '... End If
Qui il compilatore in background inserisce una linea verde ondulata sotto
cust nell'istruzione If. Il testo
dell'avviso visualizzato indica "variable 'cust' is used before it has been
assigned a value". In fase di esecuzione il risultato può essere un'eccezione
di riferimento nullo. In passato questo tipo di errore è capitato certamente
innumerevoli volte in fase di esecuzione e ora il compilatore consente di
rilevarlo in fase di compilazione.
Accidentalmente, quando si digita il codice precedente nell'editor, il
compilatore inserisce inizialmente una linea verde sotto cust
nell'istruzione Dim con il messaggio "unused local
variable 'cust'". In un primo momento ciò può sembrare fastidioso perché la
variabile è appena stata aggiunta ma alla fine aiuta a mantenere il codice più
chiaro.
Invece di mostrare tutti gli errori in Task List nell'IDE, è disponibile una nuova finestra Errors List che separa i messaggi in errori, avvisi e messaggi (vedere le figure 2 e 6). È possibile controllare se il compilatore deve indicare avvisi o errori nella scheda Compile nella progettazione applicazione, nella quale sono presenti caselle di controllo per indicare di disattivare tutti gli avvisi o di trattare tutti gli avvisi come errori.
Utilizzare l'istruzione Option Strict On per generare errori in fase di compilazione per varie situazioni. Option Strict segnalerà il codice se si tenta di eseguire una conversione verso dati più piccoli che potrebbe comportare la perdita di dati:
Dim iValue As Integer Dim lValue As Long iValue = lValue 'narrowing conversion error lValue = iValue 'ok
Viene generato un errore anche se si utilizza l'associazione tardiva. Un oggetto è associato tardivamente quando viene assegnato a una variabile di tipo Object:
Dim myObj As Object Call myObj.method1() 'late binding error
L'utilizzo di Option Strict ora è considerato come una procedura di programmazione consigliata con Visual Studio. È opportuno attivare Option Strict nel codice ove possibile. È possibile attivare Option Strict nel menu Tools | Options, nelle impostazioni Project selezionando la casella di controllo Option Strict. È anche possibile inserire l'istruzione Option Strict On all'inizio di una classe individuale o di un file di modulo.
È ora è possibile dichiarare matrici utilizzando limiti di matrice espliciti per rendere più chiara la dichiarazione:
Dim a(10) As Integer 'old way Dim b(0 To 10) As Integer 'new way
I limiti di matrice in Visual Basic sono ancora basati su zero, quindi verrà visualizzato un errore del compilatore se il limite inferiore della matrice non è 0.
Il linguaggio Visual Basic 2005 guadagna alcune importanti funzionalità e molti piccoli miglioramenti che insieme forniscono un significativo potenziamento nella facilità d'uso e nella produttività degli sviluppatori. Il linguaggio è diventato più completo e c'è una maggiore uguaglianza con il linguaggio C# su alcune importanti caratteristiche come i commenti XML e l'overload degli operatori.
Se si aggiunge la miriade di miglioramenti all'IDE, Visual Basic 2005 può essere considerato come la migliore versione di Visual Basic rilasciata finora. Non è solamente migliore dal punto di vista del linguaggio ma anche da quello assolutamente pratico dell'utilizzo. L'unico elemento di insoddisfazione può essere il fatto che non è ancora possibile generare applicazioni di produzione con Visual Basic 2005. Provate la versione Beta e sono convinto che sarete d'accordo.
Stan Schultes è un Visual Basic MVP e un curatore che contribuisce da lungo tempo con Visual Studio Magazine. È possibile visitare il suo sito Web all'indirizzo http://www.vbnetexpert.com/ per ottenere ulteriori informazioni su d lui e un elenco completo delle sue pubblicazioni.
© 2004 Microsoft Corporation . Tutti i diritti riservati. Note legali.