厳密でないデリゲート変換 (Visual Basic)

厳密でないデリゲート変換を使用すると、シグネチャが同じでない場合でも、Sub プロシージャや関数をデリゲートまたはハンドラーに割り当てることができます。 したがって、デリゲートへのバインドは、メソッドの呼び出しに対して既に許可されているバインドと整合します。

パラメーターと戻り値の型

厳密なシグネチャ一致の代わりに、厳密でない変換では、Option StrictOn に設定されている場合は次の条件を満たす必要があります。

  • 各デリゲート パラメーターのデータ型から、割り当てられた関数または Sub の対応するパラメーターのデータ型に、拡大変換が存在する必要があります。 次の例では、デリゲート Del1 に 1 つのパラメーター Integer があります。 割り当てられたラムダ式のパラメーター m には、Integer からの拡大変換に対するデータ型、LongDouble などが含まれている必要があります。

    ' 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
    

    縮小変換が許可されるのは、Option StrictOff に設定されている場合のみです。

    ' 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
    
  • 割り当てられた関数または Sub の戻り値の型から、デリゲートの戻り値の型への逆方向に、拡大変換が存在する必要があります。 次の例では、del1 の戻り値の型が Integer であるため、割り当てられている各ラムダ式の本体は、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)
    

Option StrictOff に設定されている場合、拡大制限は両方向で削除されます。

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

パラメーターの指定値の省略

厳密でないデリゲートを使用すると、割り当てられたメソッドで、パラメーターの指定値を完全に省略することもできます。

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

一部のパラメーターを指定する一方で他のパラメーターを省略することはできません。

' Not valid.
'Dim d12 As Del2 = Function(p As Integer) p

パラメーターを省略する機能は、イベント ハンドラーを定義する状況などで役立ちます。このような場合、複雑なパラメーターが複数関係しています。 一部のイベント ハンドラーについては、そのハンドラーに対する引数が使用されません。 ハンドラーは、イベントが登録されているコントロールの状態に直接アクセスし、引数を無視します。 厳密でないデリゲートを使用すると、あいまいな結果がないときに、このような宣言の引数を省略できます。 次の例では、完全に指定されたメソッド OnClickRelaxedOnClick として書き直すことができます。

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  

AddressOf の例

前の例では、ラムダ式を使用して、型の関係を簡単に確認できます。 ただし、AddressOfHandles、または AddHandler が使用されているデリゲート割り当てに対して、同じ緩和が許可されています。

次の例では、関数 f1f2f3f4 のすべてを 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

次の例は、Option StrictOff に設定されている場合にのみ有効です。

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

関数の戻り値の破棄

厳密でないデリゲート変換を使用すると、関数を Sub デリゲートに割り当てて、関数の戻り値を効果的に無視できます。 ただし、Sub を関数デリゲートに割り当てることはできません。 次の例では、関数 doubler のアドレスが 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))

関連項目