tagCANDY CGI VBレスキュー(花ちゃん) の Visual Basic 2010 用 掲示板(VB.NET 掲示板) [ツリー表示へ]   [Home]
一括表示(VB.NET VB2005)
タイトルデリゲートについて
記事No4653
投稿日: 2006/12/12(Tue) 13:39
投稿者おーかみ
はじめまして。
最近VBを使い始め、こちらのサイトを大変参考にさせてもらっていますm(__)m

ところで、物凄く間抜けな事を言っているのかもしれないのですが、
どうにも気になって困っていることがあります・・・・。


デリゲートなんですが・・・・・

何に使うんですか?これ(爆


勉強してて、あちこちのサイトで新機能だーと紹介されているのを見るわけですが
使い道がさっぱりわかりません・・・・。

いや、使い方は分かるんですが、使いどころが分からないんです・・・・。

「んな面倒くさい事せんでも普通に呼び出せばいいんでねーの?」

とか思ってしまう訳なんですが・・・・
まあ、知識がないからそう思うのでしょうが・・・・

とか、考えていると、どうにも気になって困ります。



一体どういう時使うものなのでしょうか?

[ツリー表示へ]
タイトルRe: デリゲートについて
記事No4657
投稿日: 2006/12/13(Wed) 13:05
投稿者K.J.K.
頭でっかちなだけのような。

イベントプロシージャもまたDelegateの応用例の一つですよね。
コールバックで使うとかなり楽でしょうし。

で、別に、使う必要が無ければ使わなければいいのでは。

[ツリー表示へ]
タイトルRe^2: デリゲートについて
記事No4658
投稿日: 2006/12/13(Wed) 14:26
投稿者おーかみ
おお、お返事が・・・・・はじめまして。

> 頭でっかちなだけのような。

いやはやすいません^^;
基本的に周りに聞ける人がいなくて、独学なもので・・・。
一般的な知識というより、自分が今までに必要だった事に関しての知識しかないもので、
相当偏ってるかと・・・・

> イベントプロシージャもまたDelegateの応用例の一つですよね。
> コールバックで使うとかなり楽でしょうし。

コールバックというと、「割り込みがかかると呼び出される関数」でしょうか。
どう楽なのでしょうか・・・。

というか、実はコールバックとかが分かってないと真価を発揮しない機能とかでしょうか。


> で、別に、使う必要が無ければ使わなければいいのでは。

いやまあ、実際その通りなのですが。

なんせ独学の素人なもんですから、自らの頭の悪さの為に、
実は便利な機能をまともに理解せず放置しまうのはもったいなかろうと・・・
それで聞いてみた訳なのです^^;

素人にはまだ早い世界ですかね?

[ツリー表示へ]
タイトルRe: デリゲートについて
記事No4659
投稿日: 2006/12/13(Wed) 20:35
投稿者K.J.K.
> > 頭でっかちなだけのような。
> いやはやすいません^^;
> 基本的に周りに聞ける人がいなくて、独学なもので・・・。

そういうことではなく、キーワードに拘ってしまい、その結果、
それが用いられているコードを漁って調べる方には労力が行って
いないのでは、ということです。

# 念のために書いておきますが、私は素人ですし、ほぼ独学と
# 言っても差し支えはないでしょう。

> > イベントプロシージャもまたDelegateの応用例の一つですよね。
> > コールバックで使うとかなり楽でしょうし。
> コールバックというと、「割り込みがかかると呼び出される関数」でしょうか。
> どう楽なのでしょうか・・・。

Delegateになっていれば、呼び出される関数の差し替えが効きますよね。
これにより、初めて双方向性の確保ができますし。

> というか、実はコールバックとかが分かってないと真価を発揮しない機能とかでしょうか。

まず、イベントプロシージャを使ってみてください。
これを使うことがDelegateを使うことに第一歩になります。

で、更に、VB.NETには、例えばFormのカスタマイズなどには
「イベント」と「オーバーライド」の2つ、
が使えますが、これはどう似ていて、どう異なるのでしょうか?
どう使い分けすればいいのでしょうか? そういうことを自分で
コードを書きながら確認していくといいかも知れません。
ここでDelegateの最大のメリットの1つが見出せると思います。

なんだかんだ言って、.NETの最大の特徴の1つがDelegateですから、
試行錯誤しながら、あせらずにじっくりと把握していけばいいと
思いますよ。
# 日本ではDelegateの凄まじさに言及した文章が見つかりにくい
# のには気にはなりますが。

> 素人にはまだ早い世界ですかね?

素人も玄人も関係ないでしょうね。
# もっと言えば、タイトルの類を付けている玄人こそ、こういう件では積極的に
# 教示すべきだとも考えています。

[ツリー表示へ]
タイトルRe^2: デリゲートについて
記事No4661
投稿日: 2006/12/14(Thu) 10:27
投稿者おーかみ
こんにちわ。
細かな指摘いたみいりますm(__)m

> それが用いられているコードを漁って調べる方には労力が行って
> いないのでは、ということです。

いやー、むしろ、VBtipsサイトとかのサンプルを見るにつけ、利点が分からなくなった感じがします^^;

こちらさんとか
http://www.atmarkit.co.jp/fdotnet/vb6tonet2/vbnet2_11/vbnet2_11_01.html
こちらさんとか
http://santamartadotnet.hp.infoseek.co.jp/documents/vbdotnet/eventanddelegate.html
こちらさんとか
http://www.bnote.net/vb/delegate.shtml

結局呼び出す関数を明示してるなら、普通に呼び出せばいいんでないの?・・・と。

いや、多分、これはあくまでも分かりやすく書いたもので、本質とは違うんだろうなとは
思うのですが。

「関数ポインタ」という表現で紹介されてるところも見かけるけど、その割りに、
ポインタそのものをやり取りしてるサンプルも見当たらないようで・・・・
これは探すのが下手なだけなのかもしれませんが。
つーか「関数ポインタ」がそういう使い方できるものなのかも知りませんが。

> Delegateになっていれば、呼び出される関数の差し替えが効きますよね。
> これにより、初めて双方向性の確保ができますし。

関数の差し替えということは、やはり関数のアドレスを直にやり取りして、
状況にあわせた関数をひとつの命令で使い分ける、ということでしょうか。

でも

 sub main 
    このアドレスの関数を実行しろ(Aのアドレスのポインタ)
    このアドレスの関数を実行しろ(Bのアドレスのポインタ)
 end sub

  sub このアドレスの関数を実行しろ(受け取ったアドレスのポインタ)
    指定アドレスの関数実行(受け取ったアドレスのポインタ)
 end sub

  sub A()
  ...
  end sub

 subB()
  ...
 end sub

のような感じなら素直に関数呼べばいいんじゃないかと思うわけでして・・・
それに

 sub main 
    この番号の関数を実行しろ(1)
    この番号の関数を実行しろ(2)
 end sub

  sub この番号の関数を実行しろ(受け取った数字)
  select 受け取った数字
   case 1
    A()
   case 2
    B()
  end select
 end sub

のほうが、後で分かりやすいんじゃないですかね?

使い分ける関数増える度に書き足さないと駄目ですが。




・・・・・は!?

コ コ デ ス カ ! ?

ココナンダロウカ・・・ムムム・・・



以下、考えてる事をそのままだらだら書くと、

いやでも、そもそも、結局使う関数を最初に明示してるんなら

 sub main
  A()
  B()
 end sub

で十分だよなあ・・・


「使う関数はあらかじめ決まるけど、その関数が受け取るべき引数が、プロシージャ内で決まらない」とかなら、

 sub main

  アドレス = 前処理()

  引数A=0
  引数B=100

  指定関数実行(引数A,引数B,アドレス)

 end sub

 function 前処理() as アドレス
  前処理の都合で、使う関数の種類が変わる。
  AかBの関数のアドレスのどちらかを返す。
 end function

とゆー感じか、とか考えられるけど、引数の内容も決まらないのに使うべき関数の種類が先に決まるなんて、そんな事態って起こりえるのかしら・・・

むしろ、どうあがいても、引数決らない事には関数呼べないのだから、使う関数を選ぶなんてのは最後でいいのでは・・・

という感じなのですが・・・・


解釈が基礎から間違ってるのかなあ・・・



> なんだかんだ言って、.NETの最大の特徴の1つがDelegateですから、

やはり知らぬ癖に「こんなもん使えるか!」と放り投げない方が良い感じですねえ・・・。
御指摘を頂いたイベントプロシージャ等を踏まえ、もう少し掘り下げて考えて見ます。

ご教授有難うございます。

[ツリー表示へ]
タイトルRe: デリゲートについて
記事No4662
投稿日: 2006/12/14(Thu) 11:08
投稿者K.J.K.
> > それが用いられているコードを漁って調べる方には労力が行って
> > いないのでは、ということです。
> いやー、むしろ、VBtipsサイトとかのサンプルを見るにつけ、利点が分からなくなった感じがします^^;

いや、日本語で説明されているようなところを見ても参考にはならない、と
思いますよ。まず、Delegateが使われているコードをいろいろ漁って、それを
片っ端からいじって動かしてみるべきかと。

> 解釈が基礎から間違ってるのかなあ・・・

重要なところを見落としているな、とは思います。
とりあえず、前に私は、
> で、更に、VB.NETには、例えばFormのカスタマイズなどには
> 「イベント」と「オーバーライド」の2つ、
> が使えますが、これはどう似ていて、どう異なるのでしょうか?
> どう使い分けすればいいのでしょうか? そういうことを自分で
> コードを書きながら確認していくといいかも知れません。
と書きましたのが、それを確認しましたか?

[ツリー表示へ]
タイトルRe^2: デリゲートについて
記事No4665
投稿日: 2006/12/14(Thu) 14:30
投稿者おーかみ
> いや、日本語で説明されているようなところを見ても参考にはならない、と

英語読めないと無理ありますか?^^;

> 重要なところを見落としているな、とは思います。

ムウ、ヤハリ。

> > で、更に、VB.NETには、例えばFormのカスタマイズなどには

> と書きましたのが、それを確認しましたか?

なんかネットで調べたりMSDNよく読んでみたりしてはいるんですが
ぶっちゃけ、さっぱり解らん・・・・というより、デリゲートとの繋がりが
想像できないというか。

頭も悪いんでしょうが、理解には時間がかかりそうです。

[ツリー表示へ]
タイトルRe^3: デリゲートについて
記事No4668
投稿日: 2006/12/14(Thu) 15:13
投稿者おーかみ
まだ完全に理解したわけではないのだろうなとも思いつつ、

なにが便利な機能であるのか、理解できました!


とっかかりが見えましたので、あとは自分で考えてみようと思いますm(__)m
長々と、頭の固い私にお付き合いくださり、ありがとうございます。

へっぽこ者では御座いますが、いずれはこういった場所で後からくる人に
アドバイスできる位にはなろうと、精進してまいりますm(__)m

まだ当分アドバイスもらう立場でしょうが(ヲ

[ツリー表示へ]
タイトルRe: デリゲートについて
記事No4669
投稿日: 2006/12/14(Thu) 16:12
投稿者K.J.K.
> > いや、日本語で説明されているようなところを見ても参考にはならない、と
> 英語読めないと無理ありますか?^^;

文章ではなく、コードを漁って下さい。
文章で書かれた「解答」は、本来の貴方の望む解答ではないように思えます。

弁士さんが書いているのは、確かに使い方や応用の仕方の一例としては
正解なのですが、その構造については言及してない(そもそも答えるべきものでもない)
し、なぜクラスライブラリにおいてDelegateとして分離されたのか、という
ことに対しての解答でもありません。

> なんかネットで調べたりMSDNよく読んでみたりしてはいるんですが
> ぶっちゃけ、さっぱり解らん・・・・というより、デリゲートとの繋がりが
> 想像できないというか。

.NETのライブラリの構築が、JAVAのそれや、様々なC++のそれらとどう
異なるのかを意識してみてください。旧来のライブラリの構築との間には
明確な一線がひけるのですが、それがどんなものなのかがわかるように
なれば、理解や認識も深まるでしょうし。

なぜ、ここまでくどく書いているのかといえば、貴方は「良い質問」を
しているのだと思えるからです。肝心なところに疑問を持つのは、それ
だけ重要なことですし、正解に近いところにいる、といってもいいでしょう。

[ツリー表示へ]
タイトルRe^2: デリゲートについて
記事No4677
投稿日: 2006/12/15(Fri) 08:26
投稿者おーかみ
> 文章ではなく、コードを漁って下さい。

・・・・おお、なるほど!その手が・・・・

> .NETのライブラリの構築が、JAVAのそれや、様々なC++のそれらとどう
> 異なるのかを意識してみてください。旧来のライブラリの構築との間には
> 明確な一線がひけるのですが、それがどんなものなのかがわかるように
> なれば、理解や認識も深まるでしょうし。

今回の件も、使い方が解れば今後使っていくでしょうし、
使い込めば応用や概念も理解が進んでいくものと。

物分りが悪いことにかけては定評のある私ですが、
地道にひとつひとつやっていこうと思いますm(__)m

[ツリー表示へ]
タイトルRe^3: デリゲートについて
記事No4664
投稿日: 2006/12/14(Thu) 12:05
投稿者魔界の仮面弁士
> のような感じなら素直に関数呼べばいいんじゃないかと思うわけでして・・・

それは、渡す相手が「自分自身」だった場合ですよね。
「他人」に処理を依頼する場合は、直接呼べるとは限らないわけで。

-------
たとえば、Buttonコントロールを考えてみてください。
これは、ユーザがクリック操作したときに、任意の処理を発生させるクラスです。

そして、フォーム上には、Button1_Click メソッドを用意してあります。
通常は、ButtonのClickイベントを使って、このメソッドが実行されますよね。

では、これをあえて、「イベント抜き」で考えてみましょう。



もし、その処理クラスを自分で作っているのであれば、処理クラス側から直接、
 mainForm.MyMethod(…)
などと書いて、処理対象のメソッドを直接実行させることが可能ですね。

でも、それだと「依頼側クラス」と「処理クラス」の依存度が強くなってしまい、汎用性に
乏しいですし、その処理を他のプロジェクトで使いまわすときにも都合が悪くなります。
そのクラスが、どこから呼び出されるのかは、事前には分からないわけですから。


そこで、処理クラス側が常に同じメソッドを呼ぶのではなく、依頼側から処理クラスに対して
 『ユーザがクリックしたら、私の「このメソッド」を実行して下さい』
 『計算途中でエラーが発生したら、私の「このメソッド」を呼び出して進捗を報告してください』
 『計算が完了したら、最後に、私の「このメソッド」を実行して、処理の完了を通知してください』
などといった依頼をする形にして、使い回しが利くようにしてみます。


ではこのとき、呼び出してもらう「このメソッド」を、どのようにして渡すのが良いでしょうか。

--------------
実装案1) 「この関数」を示す「メソッド名文字列」と、それを実装したオブジェクトを渡す方法。

 ' 依頼側
 obj.Foo(Me, "MyMethod")  '← Me に Public Sub MyMethod() があるとして。

 ' クラス側の実装
 Public Sub Foo(ByVal target As Object, ByVal methodName As String)
    :
  ' それらを、CallByName を使って呼び出す。
  CallByName(target, methodName, CallType.Method)
    :
 End Sub
--------------

これなら、処理クラスが、特定の依頼者に依存するという問題を軽減することができます。

でもこの方法だと、渡すべきメソッド名を間違えていても、コンパイル時には発覚しません。
それに、CallByName を使うが故に、「この関数」を Private にすることができませんね。


そこで、別案。

--------------
実装案2) 処理させる関数を、あるインターフェイスのメソッドとして実装させておき、
 そのインターフェイスを実装したクラスを渡す方法。

 ' クラス側の実装
 Public Sub Foo(ByVal target As ISample)
    :
  target.SampleMethod()
    :
 End Sub
--------------
実装案3) 「この関数」を表すデリゲートのインスタンスを渡す方法。

 ' クラス側の実装
 Public Sub Foo(ByVal target As SampleDelegate)
    :
  target()
    :
 End Sub
---------


これらの方法では、コンパイル解決もできますし、Private メソッドへの実装も可能です。



> 「関数ポインタ」という表現で紹介されてるところも見かけるけど、その割りに、
あるいは、「JavaScript でいうところの、Function オブジェクトや匿名メソッド」とか
「VBScript でいうところの、GetRef関数」などと表現されることもあるようで。

で、デリゲートを関数ポインタのように使う事はできますが、両者は異なるものです。
実際、デリゲートの方が高機能ですしね。
(VB6 時代の AddressOf は、まさに関数ポインタでしたけれども)

[ツリー表示へ]
タイトルRe^4: デリゲートについて
記事No4666
投稿日: 2006/12/14(Thu) 14:32
投稿者おーかみ
はじめましてm(__)m

まず確認ですが、

つまり、私が言っているのはすなわち

> もし、その処理クラスを自分で作っているのであれば、処理クラス側から直接、
>  mainForm.MyMethod(…)
> などと書いて、処理対象のメソッドを直接実行させることが可能ですね。

ということで、

私が解ってないないのが

> でも、それだと「依頼側クラス」と「処理クラス」の依存度が強くなってしまい、汎用性に
> 乏しいですし、その処理を他のプロジェクトで使いまわすときにも都合が悪くなります。
> そのクラスが、どこから呼び出されるのかは、事前には分からないわけですから。

この部分というわけですね?^^;

>  『ユーザがクリックしたら、私の「このメソッド」を実行して下さい』
>  『計算途中でエラーが発生したら、私の「このメソッド」を呼び出して進捗を報告してください』
>  『計算が完了したら、最後に、私の「このメソッド」を実行して、処理の完了を通知してください』
> などといった依頼をする形にして、使い回しが利くようにしてみます。


とりあえず、考え方としては・・・・


sub main

 依頼(クラス.クリックされた , クリック(のアドレス))
 依頼(クラス.エラーが起きた , エラー(のアドレス))
 依頼(クラス.作業が完了した , 完了(のアドレス))

 クラス.実処理()

sub end

sub クリック()
 ・・・
end sub

sub エラー()
 ・・・
end sub

sub 完了()
 ・・・
end sub
.
.
.
class クラス

 sub 実処理

    クリックされた()
    エラーが起きた()
    作業が完了した()

 end sub

 sub クリックされた()
  依頼されたアドレス実行
 end sub

 sub エラーが起きた()
  依頼されたアドレス実行
 end sub

 sub 作業が完了した()
  依頼されたアドレス実行
 end sub

end class


こんな感覚ですか?

でも
>  ' クラス側の実装
>  Public Sub Foo(ByVal target As SampleDelegate)
>     :
>   target()
>     :
>  End Sub

とかを見ると、なんか違うような感じだなあ
ムウン。

[ツリー表示へ]
タイトルRe^5: デリゲートについて
記事No4667
投稿日: 2006/12/14(Thu) 15:08
投稿者おーかみ
先ほどの書き込みを踏まえてVBいじってましたら、

おお、なるほど!!

わかった!解りましたよ!!
これは便利な機能デスヨ!!

えくせれんつデスヨ!!

これで野望(謎)に一歩近づきました。
いやはや、頭の悪い私に長々とお付き合いくださり、ありがとうございますm(__)m

[ツリー表示へ]