Conversão de delegado reduzida (Visual Basic)
A conversão de delegado reduzida permite atribuir assinaturas e funções a delegados ou manipuladores mesmo quando as assinaturas não são idênticas. Portanto, a associação aos delegados torna-se consistente com a associação já permitida para invocações de método.
Parâmetros e tipo de retorno
No lugar da correspondência de assinatura exata, a conversão reduzida requer que as seguintes condições sejam atendidas quando Option Strict
é definida como On
:
Uma conversão de expansão deve existir do tipo de dados de cada parâmetro delegado para o tipo de dados do parâmetro correspondente da função atribuída ou
Sub
. No exemplo a seguir, o delegadoDel1
tem um parâmetro, umInteger
. O parâmetrom
nas expressões lambda atribuídas deve ter um tipo de dados para o qual há uma conversão de expansão a partir deInteger
, comoLong
ouDouble
.' 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
Conversões de restrição são permitidas somente quando
Option Strict
é definida comoOff
.' 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
Uma conversão de expansão deve existir na direção oposta do tipo de retorno da função atribuída ou
Sub
para o tipo de retorno do delegado. Nos exemplos a seguir, o corpo de cada expressão lambda atribuída deve ser avaliado para um tipo de dados que seja ampliado paraInteger
, porque o tipo de retorno dedel1
é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
estiver definido como Off
, a restrição de ampliação será removida em ambas as direções.
' 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)
Omitir especificações de parâmetro
Os delegados reduzidos também permitem omitir completamente as especificações de parâmetro no método atribuído:
' 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))
Observe que você não pode especificar alguns parâmetros e omitir outros.
' Not valid.
'Dim d12 As Del2 = Function(p As Integer) p
A capacidade de omitir parâmetros é útil em uma situação como a definição de um manipulador de eventos, em que vários parâmetros complexos estão envolvidos. Os argumentos para alguns manipuladores de eventos não são usados. Em vez disso, o manipulador acessa diretamente o estado do controle no qual o evento é registrado e ignora os argumentos. Os delegados reduzidos permitem que você omita os argumentos nessas declarações quando não resulta nenhuma ambiguidade. No exemplo a seguir, o método OnClick
totalmente especificado pode ser reescrito como 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
Exemplos de AddressOf
As expressões lambda são usadas nos exemplos anteriores para facilitar a visualização das relações de tipo. No entanto, as mesmas reduções são permitidas nas atribuições de delegado que usam AddressOf
, Handles
ou AddHandler
.
No exemplo a seguir, as funções f1
, f2
, f3
e f4
podem todas ser atribuídas 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
O exemplo a seguir é válido somente quando Option Strict
é definida como 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))
Retornos da função de remoção
A conversão de delegados reduzida permite atribuir uma função a um delegado Sub
, ignorando efetivamente o valor retornado da função. No entanto, você não pode atribuir uma Sub
a um delegado de função. No exemplo a seguir, o endereço da função doubler
é atribuído ao delegado Sub
Del3
.
' 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))