C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: VB2005でマルチキャストデリゲート


(過去ログ 58 を表示中)

[トピック内 4 記事 (1 - 4 表示)]  << 0 >>

■33433 / inTopicNo.1)  VB2005でマルチキャストデリゲート
  
□投稿者/ たっぽ (1回)-(2009/02/27(Fri) 21:17:06)

分類:[VB.NET/VB2005 以降] 

開発環境:Microsoft Visual Studio 2005
         Professional Edition
開発言語:VB.NET
OS      :WnidowsXP SP2

マルチキャストデリゲートについて調べていまして、VB.NETでの解説見つからなかった為、
http://www.atmarkit.co.jp/fdotnet/onepoint/onepoint03/onepoint03_03.html
にある"デリゲートのマルチキャスト機能を使用したサンプル・プログラム"をVB.NETにして
動作を確認しようと考え、下記のコードを作成しました。
(そのままでもええやん、等はご勘弁を…C#は"なんとなく読める"程度なので頭の中を整理
 する意味も含めてVB.NETにしたかったんです。)


'************************コードここから*********************************
'C#コードを見る限り、コンソールアプリっぽいので
'App.Mainをここに記述
Module Module1

    Sub Main()
        Dim callable As New Callable()
        Dim caller As New Caller()
        
        caller.ShowMessage = AddressOf callable.ConcreteShowMessage
        
        Dim fancy As New Fancy()
        AddHandler caller.ShowMessage, AddressOf fancy.ShowFancyMessage
                          ~~~~~~~~~~~@
        caller.CallDelegate()

    End Sub

End Module


Delegate Sub ShowMessageDelegate(ByVal msg As String)

Class Callable
    Friend Sub ConcreteShowMessage(ByVal msg As String)
        Console.WriteLine(msg)
    End Sub
End Class

Class Caller
    Friend ShowMessage As ShowMessageDelegate
    
    Friend Sub CallDelegate()
        ShowMessage("hello, from delegate!")
    End Sub
End Class

Class Fancy
    Friend Sub ShowFancyMessage(ByVal msg As String)
        'ここでMessageBoxを使っているので
        '参照にSystem.Windows.Formsを追加する必要がある。
        System.Windows.Forms.MessageBox.Show(msg)
    End Sub 
End Class
'************************コードここまで*********************************

このコードで@の部分が構文エラーとなり、次のようなメッセージがありました。

    'ShowMessage' は 'MultiCastDelegate.Caller' のイベントではありません。

と言う事は、VB.NETではイベントで無い限りマルチキャストデリゲートが出来ない
のでしょうか?それとも、私の翻訳が間違っているのでしょうか?
出来ないなら出来ないでいいんですが…イベントとデリゲートの関係を理解する上
では、困るんでないかなぁ…と思う次第です。
(なお、当然ながら元となったコードはC#プロジェクトに貼り付けてスタートアップ
 オブジェクトの変更・参照にSystem.Windows.Formsを追加で動作しました。)

なお、エラーメッセージに従ってCallerクラスのShowMessageをイベントに書き換え
るとエラーが消え、元となったC#コードと同じ動作をしました。

'************************コードここから*********************************
Module Module1

    Sub Main()
        Dim callable As New Callable() 
        Dim caller As New Caller() 
        
        'イベントは"AddHandler 〜, AddressOf 〜 " でないとダメらしい。
        AddHandler caller.ShowMessage, AddressOf callable.ConcreteShowMessage
        
        Dim fancy As New Fancy() 
        AddHandler caller.ShowMessage, AddressOf fancy.ShowFancyMessage 
        
        caller.CallDelegate() 

    End Sub

End Module


Delegate Sub ShowMessageDelegate(ByVal msg As String) 

Class Callable 
    Friend Sub ConcreteShowMessage(ByVal msg As String) 
        Console.WriteLine(msg) 
    End Sub 
End Class 

Class Caller 
    'イベント化
    Friend Event ShowMessage As ShowMessageDelegate 
    
    Friend Sub CallDelegate() 
        RaiseEvent ShowMessage("hello, from delegate!") 
    End Sub 
End Class 

Class Fancy 
    Friend Sub ShowFancyMessage(ByVal msg As String) 
        System.Windows.Forms.MessageBox.Show(msg) 
    End Sub 
End Class 
'************************コードここまで*********************************

やっぱり、VB.NETではマルチキャストデリゲートはイベントでしか使えないのでしょうか?
どなたか、よろしくお願いします。

引用返信 編集キー/
■33434 / inTopicNo.2)  Re[1]: VB2005でマルチキャストデリゲート
□投稿者/ よねKEN (279回)-(2009/02/27(Fri) 21:42:44)
2009/02/27(Fri) 21:56:05 編集(投稿者)
DelegateクラスのCombineメソッドを使うことで実現できます。

>     Sub Main()
>         Dim callable As New Callable()
>         Dim caller As New Caller()
>         
>         caller.ShowMessage = AddressOf callable.ConcreteShowMessage
>         
>         Dim fancy As New Fancy()
>         AddHandler caller.ShowMessage, AddressOf fancy.ShowFancyMessage
>                           ~~~~~~~~~~~@
>         caller.CallDelegate()
> 
>     End Sub

Sub Main()
    Dim callable As New Callable()
    Dim caller As New Caller()
    Dim fancy As New Fancy()

    caller.ShowMessage = [Delegate].Combine( _
        New ShowMessageDelegate(AddressOf callable.ConcreteShowMessage), _
        New ShowMessageDelegate(AddressOf fancy.ShowFancyMessage))
    caller.CallDelegate()
End Sub

ここではまとめて登録するようなコード例にしちゃってますが、
caller.ShowMessage にcallable.ConcreteShowMessageの分を登録してから、
そのcaller.ShowMessageにfancy.ShowFancyMessageの分を連結して
caller.ShowMessage を追加しなおすこともできます。

> と言う事は、VB.NETではイベントで無い限りマルチキャストデリゲートが出来ない
> のでしょうか?

VBで用意されている文法での実現方法はたぶんないと思います。

> それとも、私の翻訳が間違っているのでしょうか?

方向性はあっていますが、AddHandlerの構文を見るとわかりますが、イベントにしか適用できません。

> 出来ないなら出来ないでいいんですが…イベントとデリゲートの関係を理解する上
> では、困るんでないかなぁ…と思う次第です。

VB流の方法でプログラミングする限りでは、デリゲートの存在を知らなくてもイベントが使えるようになってます。
#知っておくに越したことがないのは言うまでもないですが

引用返信 編集キー/
■33435 / inTopicNo.3)  Re[2]: VB2005でマルチキャストデリゲート
□投稿者/ よねKEN (280回)-(2009/02/27(Fri) 21:55:00)
追加情報です。

No33434 (よねKEN さん) に返信
> DelegateクラスのCombineメソッドを使うことで実現できます。

と書きましたが、引用URLのコード例の以下のあたりで書かれたコードも、
同様にコンパイルされた後はDelegate.Combineメソッドの呼び出しにコンパイルされます。
(たぶんそうだろうと思いましたが念のため、コンパイルしてildasmで確認しました)

http://www.atmarkit.co.jp/fdotnet/onepoint/onepoint03/onepoint03_03.html
-- 該当箇所の抜粋 --
caller.ShowMessage
= new ShowMessageDelegate(callable.ConcreteShowMessage);

Fancy fancy = new Fancy();
caller.ShowMessage
+= new ShowMessageDelegate(fancy.ShowFancyMessage);
-- 抜粋ここまで --
引用返信 編集キー/
■33442 / inTopicNo.4)  Re[3]: VB2005でマルチキャストデリゲート
□投稿者/ たっぽ (2回)-(2009/02/27(Fri) 23:54:59)
No33435 (よねKEN さん) に返信

>ここではまとめて登録するようなコード例にしちゃってますが、
>caller.ShowMessage にcallable.ConcreteShowMessageの分を登録してから、
>そのcaller.ShowMessageにfancy.ShowFancyMessageの分を連結して
>caller.ShowMessage を追加しなおすこともできます。

    Sub Main()
        Dim callable As New Callable()
        Dim caller As New Caller()
        Dim fancy As New Fancy()

        caller.ShowMessage = [Delegate].Combine( _
            New ShowMessageDelegate(AddressOf callable.ConcreteShowMessage) _
            )

        caller.ShowMessage = [Delegate].Combine( _
            caller.ShowMessage _
            , New ShowMessageDelegate(AddressOf fancy.ShowFancyMessage))

        caller.CallDelegate()
    End Sub

のようにすれば良いのですね。
さらに連結が必要な場合は、同様に記述を繰り返していく…っと。


>方向性はあっていますが、AddHandlerの構文を見るとわかりますが、イベントにしか適用できません。
ごめんなさい、まずそれを確認するべきでした…orz

>VB流の方法でプログラミングする限りでは、デリゲートの存在を知らなくてもイベントが使えるようになってます。
ですねぇ。楽っちゃ楽なんですが、手元にある参考書にはデリゲートの事も書いてありまして興味を持った次第です。
でもマルチキャストデリゲートについては1ページほどしか記述が無くて…消化不良をおこしました。

> 追加情報です。
> 
> ■No33434 (よねKEN さん) に返信
>>DelegateクラスのCombineメソッドを使うことで実現できます。
> 
> と書きましたが、引用URLのコード例の以下のあたりで書かれたコードも、
> 同様にコンパイルされた後はDelegate.Combineメソッドの呼び出しにコンパイルされます。
> (たぶんそうだろうと思いましたが念のため、コンパイルしてildasmで確認しました)
> 
> http://www.atmarkit.co.jp/fdotnet/onepoint/onepoint03/onepoint03_03.html
> -- 該当箇所の抜粋 --
> caller.ShowMessage
>     = new ShowMessageDelegate(callable.ConcreteShowMessage);
> 
> Fancy fancy = new Fancy();
> caller.ShowMessage
>     += new ShowMessageDelegate(fancy.ShowFancyMessage);
> -- 抜粋ここまで --

ここまでして頂けるとは…ありがとうございます。
VBしか使えないので、中間コードの見方などさっぱりでしたが…
"ildasm"なんてキーワードも知る事ができて、思いがけない知識も頂けました。
時間ができたら、こちらも調査したいと思います。

本当に、ありがとうございました。

解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -