Conversione di tipo relaxed del delegato
Aggiornamento: novembre 2007
La conversione relaxed del delegato, introdotta in Visual Basic 2008, consente di assegnare subroutine e funzioni a delegati o gestori anche quando le firme non sono identiche. Pertanto, l'associazione ai delegati diventa coerente con l'associazione già consentita nelle chiamate ai metodi.
Parametri e tipo restituito
Al posto della corrispondenza esatta delle firme, la conversione relaxed richiede il rispetto delle condizioni seguenti quando l'oggetto Option Strict è impostato su On:
Una conversione verso un tipo di dati più grande è possibile dal tipo di dati di ogni parametro del delegato al tipo di dati del parametro corrispondente della funzione assegnata o Sub. Nell'esempio seguente, il delegato Del1 dispone di un parametro, ovvero di un oggetto Integer. Il parametro m nelle espressioni lambda assegnate deve avere un tipo di dati per il quale vi sia una conversione verso un tipo di dati più grande da Integer, ad esempio Long o Double.
' Definition of delegate Del1. Delegate Function Del1(ByVal arg As Integer) As Integer
' Valid lambda expression assignments with Option Strict on or off: ' Integer matches Integer. Dim d1 As Del1 = Function(m As Integer) 3 ' Integer widens to Long Dim d2 As Del1 = Function(m As Long) 3 ' Integer widens to Double Dim d3 As Del1 = Function(m As Double) 3
Le conversioni verso un tipo di dati più piccolo sono consentite solo quando Option Strict è impostato su Off.
' Valid only when Option Strict is off: Dim d4 As Del1 = Function(m As String) CInt(m) Dim d5 As Del1 = Function(m As Short) m
Una conversione verso un tipo di dati più grande è possibile nella direzione opposta dal tipo restituito della funzione assegnata o Sub al tipo restituito del delegato. Negli esempi seguenti, il corpo di ogni espressione lambda assegnata deve restituire un tipo di dati che viene convertito verso il tipo più grande Integer poiché il tipo restituito dell'oggetto del1 è Integer.
' Valid return types with Option Strict on: ' Integer matches Integer. Dim d6 As Del1 = Function(m As Integer) m ' Short widens to Integer. Dim d7 As Del1 = Function(m As Long) CShort(m) ' Byte widens to Integer. Dim d8 As Del1 = Function(m As Double) CByte(m)
Se Option Strict è impostato su Off, la restrizione per la conversione verso un tipo di dati più grande viene rimossa in entrambe le direzioni.
' Valid only when Option Strict is set to Off.
' Integer does not widen to Short in the parameter.
Dim d9 As Del1 = Function(n As Short) n
' Long does not widen to Integer in the return type.
Dim d10 As Del1 = Function(n As Integer) CLng(n)
Omissione delle specifiche dei parametri
I delegati di tipo relaxed consentono inoltre di omettere completamente le specifiche dei parametri nel metodo assegnato:
' Definition of delegate Del2, which has two parameters.
Delegate Function Del2(ByVal arg1 As Integer, ByVal arg2 As String) As Integer
' The assigned lambda expression specifies no parameters, even though
' Del2 has two parameters. Because the assigned function in this
' example is a lambda expression, Option Strict can be on or off.
' Compare the declaration of d16, where a standard function is assigned.
Dim d11 As Del2 = Function() 3
' The parameters are still there, however, as defined in the delegate.
Console.WriteLine(d11(5, "five"))
' Not valid.
' Console.WriteLine(d11())
' Console.WriteLine(d11(5))
Tenere presente che non è possibile specificare alcuni parametri e ometterne altri.
' Not valid.
'Dim d12 As Del2 = Function(p As Integer) p
La possibilità di omettere i parametri è utile in una situazione quale la definizione di un gestore eventi, in cui sono implicati vari parametri complessi. Gli argomenti per alcuni gestori eventi non sono utilizzati. Invece, il gestore accede direttamente allo stato del controllo nel quale l'evento è registrato e ignora gli argomenti. I delegati di tipo relaxed consentono di omettere gli argomenti in tali dichiarazioni quando non risultano ambiguità. Nell'esempio seguente, il metodo OnClick pienamente specificato può essere riscritto come RelaxedOnClick.
Sub OnClick(ByVal sender As Object, ByVal e As EventArgs) Handles b.Click
MessageBox.Show("Hello World from" + b.Text)
End Sub
Sub RelaxedOnClick() Handles b.Click
MessageBox.Show("Hello World from" + b.Text)
End Sub
Esempi di AddressOf
Le espressioni lambda vengono utilizzate negli esempi precedenti per rendere facilmente individuabili le relazioni dei tipi. Tuttavia, le stesse conversioni di tipo relaxed sono consentite per le assegnazioni del delegato che utilizzano AddressOf, Handles o AddHandler.
Nell'esempio seguente le funzioni f1, f2, f3 e f4 possono essere tutte assegnate a Del1.
' Definition of delegate Del1.
Delegate Function Del1(ByVal arg As Integer) As Integer
' Definitions of f1, f2, f3, and f4.
Function f1(ByVal m As Integer) As Integer
End Function
Function f2(ByVal m As Long) As Integer
End Function
Function f3(ByVal m As Integer) As Short
End Function
Function f4() As Integer
End Function
' Assignments to function delegate Del1.
' Valid AddressOf assignments with Option Strict on or off:
' Integer parameters of delegate and function match.
Dim d13 As Del1 = AddressOf f1
' Integer delegate parameter widens to Long.
Dim d14 As Del1 = AddressOf f2
' Short return in f3 widens to Integer.
Dim d15 As Del1 = AddressOf f3
L'esempio seguente è valido solo quando Option Strict è impostato su Off.
' If Option Strict is Off, parameter specifications for f4 can be omitted.
Dim d16 As Del1 = AddressOf f4
' Function d16 still requires a single argument, however, as specified
' by Del1.
Console.WriteLine(d16(5))
' Not valid.
'Console.WriteLine(d16())
'Console.WriteLine(d16(5, 3))
Eliminazione dei risultati delle funzioni
La conversione di tipo relaxed del delegato consente di assegnare una funzione a un delegato Sub, ignorando efficacemente il valore restituito della funzione. Tuttavia, non è possibile assegnare una Sub a un delegato della funzione. Nell'esempio seguente, l'indirizzo della funzione doubler viene assegnato al delegato SubDel3.
' Definition of Sub delegate Del3.
Delegate Sub Del3(ByVal arg1 As Integer)
' Definition of function doubler, which both displays and returns the
' value of its integer parameter.
Function doubler(ByVal p As Integer) As Integer
Dim times2 = 2 * p
Console.WriteLine("Value of p: " & p)
Console.WriteLine("Double p: " & times2)
Return times2
End Function
' You can assign the function to the Sub delegate:
Dim d17 As Del3 = AddressOf doubler
' You can then call d17 like a regular Sub procedure.
d17(5)
' You cannot call d17 as a function. It is a Sub, and has no
' return value.
' Not valid.
'Console.WriteLine(d17(5))
Vedere anche
Attività
Procedura: passare una routine a un'altra routine in Visual Basic
Procedura: scrivere gestori eventi
Concetti
Conversioni di ampliamento e restrizione
Delegati e operatore AddressOf