delegate
public delegate CheckItem CheckDelegate();
private CheckDelegate getCheckMethodByName(CheckItemList p_Cil, string p_MethodName)
{
MethodInfo l_MethodInstance = null;
try
{
l_MethodInstance = p_Cil.GetType().GetMethod(p_MethodName, BindingFlags.Instance | BindingFlags.Public);
return (CheckDelegate)Delegate.CreateDelegate(typeof(CheckDelegate), p_Cil, l_MethodInstance);
}
catch (Exception p_Ex)
{
throw new Exception("查無此方法: Error:" + p_Ex.Message);
}
}
from http://kan-kikuchi.hatenablog.com/entry/Delegate
まず、Test2の
上記のような感じでデリゲートの宣言が必要なくなります。
ActionとFuncを使うにはusing System; が必要なので忘れずに。
こうするとdelegateMethodを実行するだけで、
簡単!引数がなければdelegateの後に{}付け、その中に処理を書くだけ。
返り値がある場合は通常のメソッドと同様、returnを使いましょう。
delegateと{}が無くなり、より簡潔になりました。({}は付けても良い)
なんと、引数の型まで省略できてしまいます。
なんとなく自分のイメージでは、
デリゲートとは
そもそもデリゲートとは何かと言えば、
デリゲートは日本語では「委譲」と訳されることが多い。委譲という言葉が分かりにくいと思うなら、代表者と考えてもよい。何かの処理を実行させたいときに、処理機能を持つメソッドを直接呼び出すのではなく、代表者に処理を求めるのである。代表者は処理機能は持っていないが、それを処理できる適切なメソッドを知っており、そのメソッドに処理要求を渡す。
との事。もっと簡潔に言うのであれば、
ざっくり言うと、デリゲートとは関数を入れられる変数です。
みたいな感じ。
自分で説明しようとしたけど、ググった先の方が分かり易かったパターンですねはい。
デリゲートの使い道としてよくあるのがコールバックで、
その処理終わったらこのメソッド実行して!
みたいな形でメソッドを渡す場合に使います。
使い方
まずデリゲートを使った例を以下に示します。
処理内容はTestというクラスのMethodを実行すると、Test2のインスタンスを作成し、
Test2のMethodを実行するというものです。
このTest2のMethodを実行する際に、
Testに実装されているCallBackというメソッドをデリゲートとして渡しています。
まず、Test2の
public delegate void Delegate();
の所でどのようなメソッドをデリゲートととして渡せるかを宣言しています。
引数や返り値を付ける事も可能です。
また、Test1の
Test2.Delegate delegateMethod = CallBack;
でデリゲートの宣言を行っています。変数を宣言するのと同様ですね。
もちろん変数を作成せず、
test2.Method(CallBack);
という形でも問題ありません。
このようにメソッドを他の変数と同じ形で使う事ができるのがデリゲートです。
FuncとAction
先ほどの例のように、デリゲートの形式をいちいち宣言するのがめんどくさい!
てな時に使えるのが、FuncとActionです。
上記のような感じでデリゲートの宣言が必要なくなります。
また、引数や返り値が必要な場合が以下のようになります。
返り値が無い場合がAction、有る場合が Funcです。
ActionとFuncを使うにはusing System; が必要なので忘れずに。
privateメソッドを渡す
デリゲートではprivateメソッドを渡す事も可能です。
デリゲート・インスタンスを作成する時点で、呼び出すべきメソッドへのアクセス権限があればよいのであって、メソッド呼び出しそのものを行うときにはアクセス権限がなくてもよい。
という事で、先ほどのCallBackというメソッドがprivateメソッドでも問題無く実行出来ます。
複数のメソッドを渡す
デリゲートには複数のメソッドを設定する事が可能です。
以下の例のように+=演算子を用いて追加していきます。
こうするとdelegateMethodを実行するだけで、
CallBack1〜3の3つのメソッドを実行する事が可能です。
匿名メソッド
デリゲートの為だけにメソッドを作るのはちょっと……
みたいな時に使えるのが匿名メソッドです。
例のCallBackメソッドを匿名メソッドにすると以下の通り。
簡単!引数がなければdelegateの後に{}付け、その中に処理を書くだけ。
引数がある場合は以下のように()内に設定します。
返り値がある場合は通常のメソッドと同様、returnを使いましょう。
ラムダ式
やっと出ましたラムダ式。
ラムダ式は先ほどの匿名メソッドの一種で、より簡潔に匿名関数が作れます。
先ほどCallBackの匿名メソッドをラムダ式で書くと以下の通りです。
delegateと{}が無くなり、より簡潔になりました。({}は付けても良い)
間の()は引数を設定する場所ですが、引数が無いのでただの括弧だけになっています。
という事で引数がある場合は以下の通りです。
なんと、引数の型まで省略できてしまいます。
ちょっと省略し過ぎな気もしますが、かなり簡潔にはなりますね。
Event
さて最後にもう一つの疑問、DelegateとEventの違いについてです。
実はEventはDelegateの一種でほとんど同じ機能を持っていますが、
一部仕様が異なり、それにより使い方も変わってきます。
C# の event は delegate のようにメソッドを登録することができます。
ただし、以下の点が違います。
- ローカルな変数には使えず、必ずクラスのメンバー
- 同じクラスのメソッドからのみ呼び出し可能
つまり、自分でメソッドを登録して他のクラスに渡すのでは無く、
他のクラスにメソッドを登録しといてもらい、特定のタイミングでそれを実行するという感じですね。
例えば、ボタンが押されたかを監視しているクラスに、
ボタンが押された際のメソッドを登録するといった具合です。
NGUIのUIButtonが正しくその通りの形になっています。
実装は以下のようにeventを付けるだけです。
なんとなく自分のイメージでは、
これ使って!と渡すのがDelegateで
こっちで使うから登録しといて!とするのがEvent
なのかなと思いました。
もちろんDelegateでEventと同様の機能も実装出来ますが、
安全性を考え、使い分けていきたいものです。
留言
張貼留言