作成日: 2015/12/03, 更新日: 2015/12/03
デリゲートの特徴を1つ1つ噛み砕いて、苦手意識を克服しよう
デリゲート、それはよく分からないもの。
- デリゲート、日本語の意味は「委譲」、つまり代理人。
- 「デリゲート」で考えてみると、ちょっと聞きなれない言葉で、よく分からないものというイメージで身構えてしまいますが、 「代理人」で考えてみると、実は、今の世の中には、代理人であふれかえっていることが分かります。
- 印刷代行、運転代行、決済代行、家事代行、育児代行。このように、いろいろなサービスがあります。 要するに、本人の代わりにやってあげるよ。というお仕事ですね。
スポンサーリンク
デリゲート、それはメイドさん。
- 例えば、欧米の場合、執事やメイド等の使用人を雇って、生活面をサポートしてもらうところが多いです。 今日は、そんな使用人の仕事内容について、勉強していきます。
使用人のお仕事、仕事代行。
- 使用人は、食事の準備や掃除、洗濯を代わりにやってくれます。中には秘書のように、スケジュール管理もやってくれるところもあります。 しかし、宿題面倒くさいから代わりにやって。仕事行きたくないから代わりに行ってやってきて。というお願いは聞いてくれません。 何でもかんでも、代わりにやってくれるわけではないのです。
- VB.NET の Delegate も代行のお仕事をしてくれます。あー、メソッド呼び出すの面倒くさいな、誰か代わりに呼んでくれないかな。 というお願いを、Delegate は引き受けてくれます。
Dim i1 As Integer = 0 ' 足し算 i1 = Me.Plus(3, 2) ' あー、呼び出すのだりぃ。 Console.WriteLine("3+2={0}", i1) ' 引き算 i1 = Me.Minus(3, 2) ' あー、呼び出すのかったりぃ。 Console.WriteLine("3-2={0}", i1) Function Plus(i1 As Integer, i2 As Integer) As Integer Return i1 + i2 End Function Function Minus(i1 As Integer, i2 As Integer) As Integer Return i1 - i2 End Function
' 出力結果 3+2=5 3-2=1
Dim dlgt As CalcDelegate = New CalcDelegate(AddressOf Me.Plus) ' このようにも書ける ' 足し算メソッドの代わりとなる dlgt = AddressOf Me.Plus ' 代行呼び出し、お願いしますね!>あいよー! Console.WriteLine("3+2={0}", dlgt(3, 2)) ' あらよっとー! ' 引き算メソッドの代わりとなる dlgt = AddressOf Me.Minus ' 代行呼び出し、お願いしますね!>あいよー! Console.WriteLine("3-2={0}", dlgt(3, 2)) ' あらよっとー! Delegate Function CalcDelegate(i1 As Integer, i2 As Integer) As Integer Function Plus(i1 As Integer, i2 As Integer) As Integer Return i1 + i2 End Function Function Minus(i1 As Integer, i2 As Integer) As Integer Return i1 - i2 End Function
' 出力結果 3+2=5 3-2=1
Public Class Form1 Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load Dim i1 As Integer = 0 ' 足し算 i1 = Calc.Calculate(3, 2, AddressOf Me.Plus) Console.WriteLine("3+2={0}", i1) ' 引き算 i1 = Calc.Calculate(3, 2, AddressOf Me.Minus) Console.WriteLine("3-2={0}", i1) End Sub Function Plus(i1 As Integer, i2 As Integer) As Integer Return i1 + i2 End Function Function Minus(i1 As Integer, i2 As Integer) As Integer Return i1 - i2 End Function End Class
Public Class Calc Public Delegate Function CalcDelegate(i1 As Integer, i2 As Integer) As Integer Public Shared Function Calculate(i1 As Integer, i2 As Integer, method As CalcDelegate) As Integer Return method(i1, i2) End Function End Class
' 出力結果 3+2=5 3-2=1
スポンサーリンク
使用人のお仕事、多重代行。
- 前節で述べた通り、使用人は、とにかく、いろいろやることがあります。 家事が終わると、庭の手入れや子供たちの送迎、食材の購入、クリーニング等、次から次へと、段取り良くテキパキこなします。
- VB.NET の Delegate もいろいろやります。頼まれた仕事はテキパキこなします。
' 1メソッド1デリゲートで用意して、デリゲートにまとめて登録 Dim i1 As Integer = 0 Dim plusMethod As CalcDelegate = AddressOf Me.Plus Dim minusMethod As CalcDelegate = AddressOf Me.Minus Dim multiMethod As CalcDelegate = CType([Delegate].Combine(New CalcDelegate() {plusMethod, minusMethod}), CalcDelegate) ' まとめたデリゲートを1つ1つ実行して、戻り値を受け取る Dim methodList() As [Delegate] = multiMethod.GetInvocationList() For Each method As CalcDelegate In methodList i1 = method(3, 2) Console.WriteLine(i1) Next
' 出力結果 5 1
Dim d1 As MethodInvoker = AddressOf Me.EatBreakfast Dim d2 As MethodInvoker = AddressOf Me.EatLunch Dim d3 As MethodInvoker = AddressOf Me.EatDinner Dim d4 As MethodInvoker = CType([Delegate].Combine(New MethodInvoker() {d1, d2, d3}), MethodInvoker) ' 複数実行 d4() Sub EatBreakfast() Console.WriteLine("Eat! Breakfast.") End Sub Sub EatLunch() Console.WriteLine("Eat! Lunch.") End Sub Sub EatDinner() Console.WriteLine("Eat! Dinner.") End Sub
' 出力結果 Eat! Breakfast. Eat! Lunch. Eat! Dinner.
使用人のお仕事、非同期実行。
- 使用人は、ご主人様とは別の人間なので、ご主人様が仕事している時に、洗濯、掃除等他の仕事をすることができます。 人間の世界で考えると、人々が非同期で活動しているのって、ごくごく当たり前なことですよね。 例えば、会社だと、営業が各自で外周りしたり、上司が得意先とそれぞれの会議室で会議したり、とかですね。 使用人にしても、1人で掃除や買い物するのではなく、2人いれば、掃除担当と買い物担当で分けてやれば、それぞれ同時にこなせますね。
- VB.NET の Delegate も非同期実行ができます。
Imports System.Threading.Thread Dim method As New MethodInvoker(AddressOf Me.DoWork) method() Console.WriteLine("全て終了") Sub DoWork() Console.WriteLine("開始") Sleep(3000) Console.WriteLine("終了") End Sub
' 出力結果 開始 終了 全て終了
Imports System.Threading.Thread Dim method As New MethodInvoker(AddressOf Me.DoWork) method.BeginInvoke(Nothing, Nothing) Console.WriteLine("全て終了") Sub DoWork() Console.WriteLine("開始") Sleep(3000) Console.WriteLine("終了") End Sub
' 出力結果 全て終了 開始 終了
Imports System.Threading.Thread Public Class Form1 ' クラス変数にして、各メソッドからアクセスできるようにしている Private method As MethodDelegate = Nothing Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load method = AddressOf Me.Plus method.BeginInvoke(3, 2, New AsyncCallback(AddressOf Me.CallBack), "すべて終了") Console.WriteLine("開始") End Sub Delegate Function MethodDelegate(i1 As Integer, i2 As Integer) As Integer Function Plus(i1 As Integer, i2 As Integer) As Integer Sleep(1000) Return i1 + i2 End Function Sub CallBack(ar As IAsyncResult) Dim result As Integer = method.EndInvoke(ar) Dim msg As String = ar.AsyncState.ToString() Console.WriteLine(result) Console.WriteLine(msg) End Sub End Class
' 出力結果 開始 5 すべて終了
まとめ。
- 使用人のお仕事がいかに大変か、お分かりになられたでしょうか。 ではなくて、ここまで Delegate について勉強してきましたが、いかがでしたでしょうか。
- 近年では、VB2005 で登場して、VB2008 で強化された、ジェネリックデリゲートがたくさん登場しています。 本記事内では毎回独自のデリゲートを定義していましたが、ジェネリックの機能により、あらゆるパターンのデリゲートを作成することができるようになりました。 独自のデリゲートを準備することなくデリゲートを使えるので、大変便利になりました。 ジェネリックについてはこちらを参照ください。
- Delegate を知ることは、イベントの仕組みを知ることにつながります。ここまで頑張って読まれた方であれば、イベントの仕組みも楽勝です!それでは。
- 最後までこの記事を読んでいただき、ありがとうございました。
スポンサーリンク