ドリィちゃんから
デリゲートの説明を押し付けられたから解説するピヨ。
デリゲートとは(うんたらかんたら)と説明されるのは眠たいと思うので早速このコードをコピペして実行してみて。
Imports System
Public Class Program
Private Delegate Function SimpleComputer( _
ByVal val As Byte, ByVal val1 As Byte) As Double
Private Shared Function Add( _
ByVal val As Byte, ByVal val1 As Byte) As Double
Dim rval As Double = CType(val, Double) + CType(val1, Double)
Console.Write("{0}と{1}の足し算を行います。", val, val1)
Console.Write("答えは【{0}】です。" & vbLf, rval)
Return rval
End Function
Private Shared Function Subtract( _
ByVal val As Byte, ByVal val1 As Byte) As Double
Dim rval As Double = CType(val, Double) - CType(val1, Double)
Console.Write("{0}と{1}の引き算を行います。", val, val1)
Console.Write("答えは【{0}】です。" & vbLf, rval)
Return rval
End Function
Private Shared Function Multiply( _
ByVal val As Byte, ByVal val1 As Byte) As Double
Dim rval As Double = CType(val, Double) * CType(val1, Double)
Console.Write("{0}と{1}の掛け算を行います。", val, val1)
Console.Write("答えは【{0}】です。" & vbLf, rval)
Return rval
End Function
Private Shared Function Divide( _
ByVal val As Byte, ByVal val1 As Byte) As Double
Dim rval As Double = CType(val, Double) / CType(val1, Double)
Console.Write("{0}と{1}の割り算を行います。", val, val1)
Console.Write("答えは【{0}】です。" & vbLf, rval)
Return rval
End Function
Private Shared Function Calculate( _
ByVal val As Byte, ByVal val1 As Byte, ByRef fun As SimpleComputer) _
As Double
fun(val, val1)
End Function
Private Shared Sub SingleExe()
Console.WriteLine("********************" & _
"一つずつメソッドを呼び出して計算します********************")
Dim ran As Random = New Random( _
CType(Math.Min(DateTime.Now.Ticks, Integer.MaxValue), Integer))
Dim val As Byte = CByte(ran.Next(1, 100))
Dim val1 As Byte = CByte(ran.Next(1, 100))
Calculate(Val, val1, AddressOf Add)
val = CByte(ran.Next(1, 100))
val1 = CByte(ran.Next(1, 100))
Calculate(Val, val1, AddressOf Subtract)
val = CByte(ran.Next(1, 100))
val1 = CByte(ran.Next(1, 100))
Calculate(Val, val1, AddressOf Multiply)
val = CByte(ran.Next(1, 100))
val1 = CByte(ran.Next(1, 100))
Calculate(Val, val1, AddressOf Divide)
Console.WriteLine("")
End Sub
Private Shared Sub MultiExe()
Console.WriteLine("********************" & _
"一度にメソッド呼び出して計算します********************")
Dim addfun As SimpleComputer = New SimpleComputer(AddressOf Add)
Dim subfun As SimpleComputer = New SimpleComputer(AddressOf Subtract)
Dim mulfun As SimpleComputer = New SimpleComputer(AddressOf Multiply)
Dim divfun As SimpleComputer = New SimpleComputer(AddressOf Divide)
Dim allfun As SimpleComputer = Nothing
allfun = CType(System.Delegate.Combine(allfun, addfun), SimpleComputer)
allfun = CType(System.Delegate.Combine(allfun, subfun), SimpleComputer)
allfun = CType(System.Delegate.Combine(allfun, mulfun), SimpleComputer)
allfun = CType(System.Delegate.Combine(allfun, divfun), SimpleComputer)
Dim ran As Random = New Random( _
CInt(Math.Min(DateTime.Now.Ticks, Integer.MaxValue)))
Dim val As Byte = CByte(ran.Next(1, 100))
Dim val1 As Byte = CByte(ran.Next(1, 100))
Calculate(val, val1, allfun)
Console.WriteLine("")
Console.WriteLine("********************" & _
"割り算以外を計算します********************")
allfun = CType(System.Delegate.Remove(allfun, divfun), SimpleComputer)
val = CByte(ran.Next(1, 100))
val1 = CByte(ran.Next(1, 100))
Calculate(val, val1, allfun)
Console.WriteLine("")
End Sub
Shared Sub Main()
SingleExe()
MultiExe()
End Sub
End Class
ちょっと長いけど勘弁してね。どう?実行した?面白い動きをするでしょ?ピヨ?ピヨ?
でも一応解説して欲しいと思うから一つずつ解説するッピヨ。
まずはデリゲートの宣言を見てみよう。
Private Delegate Function SimpleComputer( _
ByVal val As Byte, ByVal val1 As Byte) As Double
何かメソッドの定義みたいだね。と思った貴方は鋭い!。
デリゲートの宣言はメソッドの定義を決めるのに等しいピヨ。
このサンプルコードの場合は、
Double型の値を返す、二つのByte型の値を受け取るメソッド
を表しているんだ。これが何を意味するかは、これから解説するピヨ。
次に注目するべきなのは、
Calculateメソッドピヨォ。
三つ目の引数にSimpleComputerデリゲートを受け取っているよね。
それの使い方を見て。メソッドの呼び出しそのものピヨ。
だからボクはさっきメソッドの定義に等しいと表現したんだ。
今のところデリゲートは単純そうに見えるんだけど、
デリゲートの機能は単純にメソッドを呼び出すだけではないんだ。
なんと!一度に複数のメソッドを一気に呼び出せるんだ。全て同じ値で計算されているからそれが分かるピヨ。
MultiExeメソッド内の処理を見てごらん。
Calculate( val, val1, allfun )
が一回しか呼んでいないピヨ。
でもちゃんと全部メソッドを呼んでいるよね。どう?不思議だよね。
これにはちゃんとしたトリックがあるんだ。そのトリックは、
Delegate.Invokeメソッドさ。
このメソッドが暗黙的に使用されて
一つのデリゲート内に複数のメソッドを格納できるんだ。
だから一回呼べば全て呼ばれるんだ。これを応用すれば面白いソフトが作れるよ。色々妄想すると楽しいピヨ。
勿論、逆の処理も可能で、
Delegate.Removeメソッドを使用すれば、
使用しなくなったメソッドを除外できよ。これも覚えておいてね。
じゃあこれでお終い!