Conversão de delegado relaxado (Visual Basic)

A conversão de delegação relaxada permite atribuir subs e funções a delegados ou manipuladores, mesmo quando suas assinaturas não são idênticas. Portanto, a vinculação a delegados torna-se consistente com a vinculação já permitida para invocações de método.

Parâmetros e tipo de retorno

Em vez da correspondência exata de assinatura, a conversão relaxada requer que as seguintes condições sejam atendidas quando Option Strict estiver definida como On:

  • Uma conversão de ampliaçã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 delegado Del1 tem um parâmetro, um Integer. O parâmetro m nas expressões lambda atribuídas deve ter um tipo de dados para o qual há uma conversão de ampliação de Integer, como Long ou 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
    

    O estreitamento de conversões só é permitido quando Option Strict definido como 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
    
  • Uma conversão de ampliação deve existir na direção oposta do tipo de retorno da função atribuída ou Sub do 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 se amplia para Integer porque o tipo de retorno de 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 estiver definido como Off, a restrição de alargamento é 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)

Omitindo especificações de parâmetros

Delegados relaxados também permitem que você omita completamente as especificações de parâmetros 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 não é possível 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, onde 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. Delegados relaxados permitem que você omita os argumentos em tais declarações quando não resultam ambiguidades. 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  

EndereçoDe exemplos

As expressões lambda são usadas nos exemplos anteriores para tornar as relações de tipo fáceis de ver. No entanto, as mesmas flexibilizações são permitidas para atribuições delegadas que usam AddressOf, Handlesou AddHandler.

No exemplo a seguir, as funções , , , e f4 todas podem ser atribuídas a Del1. f3f2f1

' 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 definido 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))

Função de descartamento retorna

A conversão de delegação relaxada permite atribuir uma função a um Sub delegado, ignorando efetivamente o valor de retorno da função. No entanto, não é possível atribuir um Sub a um delegado de função. No exemplo a seguir, o endereço da função doubler é atribuído a Sub delegar 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))

Consulte também