Relaxed delegate conversion enables you to assign subs and functions to delegates or handlers even when their signatures are not identical. Therefore, binding to delegates becomes consistent with the binding already allowed for method invocations.
Parameters and Return Type
In place of exact signature match, relaxed conversion requires that the following conditions be met when Option Strict
is set to On
:
A widening conversion must exist from the data type of each delegate parameter to the data type of the corresponding parameter of the assigned function or Sub
. In the following example, the delegate Del1
has one parameter, an Integer
. Parameter m
in the assigned lambda expressions must have a data type for which there is a widening conversion from Integer
, such as Long
or Double
.
Delegate Function Del1(ByVal arg As Integer) As Integer
Dim d1 As Del1 = Function(m As Integer) 3
Dim d2 As Del1 = Function(m As Long) 3
Dim d3 As Del1 = Function(m As Double) 3
Narrowing conversions are permitted only when Option Strict
is set to Off
.
Dim d4 As Del1 = Function(m As String) CInt(m)
Dim d5 As Del1 = Function(m As Short) m
A widening conversion must exist in the opposite direction from the return type of the assigned function or Sub
to the return type of the delegate. In the following examples, the body of each assigned lambda expression must evaluate to a data type that widens to Integer
because the return type of del1
is Integer
.
Dim d6 As Del1 = Function(m As Integer) m
Dim d7 As Del1 = Function(m As Long) CShort(m)
Dim d8 As Del1 = Function(m As Double) CByte(m)
If Option Strict
is set to Off
, the widening restriction is removed in both directions.
Dim d9 As Del1 = Function(n As Short) n
Dim d10 As Del1 = Function(n As Integer) CLng(n)
Omitting Parameter Specifications
Relaxed delegates also allow you to completely omit parameter specifications in the assigned method:
Delegate Function Del2(ByVal arg1 As Integer, ByVal arg2 As String) As Integer
Dim d11 As Del2 = Function() 3
Console.WriteLine(d11(5, "five"))
Note that you cannot specify some parameters and omit others.
The ability to omit parameters is helpful in a situation such as defining an event handler, where several complex parameters are involved. The arguments to some event handlers are not used. Instead, the handler directly accesses the state of the control on which the event is registered, and ignores the arguments. Relaxed delegates allow you to omit the arguments in such declarations when no ambiguities result. In the following example, the fully specified method OnClick
can be rewritten as 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
Lambda expressions are used in the previous examples to make the type relationships easy to see. However, the same relaxations are permitted for delegate assignments that use AddressOf
, Handles
, or AddHandler
.
In the following example, functions f1
, f2
, f3
, and f4
can all be assigned to Del1
.
Delegate Function Del1(ByVal arg As Integer) As Integer
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
Dim d13 As Del1 = AddressOf f1
Dim d14 As Del1 = AddressOf f2
Dim d15 As Del1 = AddressOf f3
The following example is valid only when Option Strict
is set to Off
.
Dim d16 As Del1 = AddressOf f4
Console.WriteLine(d16(5))
Dropping Function Returns
Relaxed delegate conversion enables you to assign a function to a Sub
delegate, effectively ignoring the return value of the function. However, you cannot assign a Sub
to a function delegate. In the following example, the address of function doubler
is assigned to Sub
delegate Del3
.
Delegate Sub Del3(ByVal arg1 As Integer)
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
Dim d17 As Del3 = AddressOf doubler
d17(5)