メニュー

プロダクト



プログラミング


  • Java
    • Web 技術
    • メール技術
      • JavaMail
      • Apache James Mailet
    • Web フレームワーク
      • Jakarta Struts
      • Jakarta Velocity
      • Jakarta Tapestry
      • WebWork2
      • Jakarta Jetspeed
      • Apache Cocoon 2
    • DB 技術
      • JDBC
      • Hibernate
      • Apache Torque
    • DI (IoC) コンテナ
      • Spring Framework
      • Seasar2
      • Apache HiveMind
      • PicoContainer
    • 属性プログラミング
    • テスティング
      • JUnit
      • Jakarta Cactus
      • DBUnit
      • djUnit
      • FitNesse
    • ロギング
      • Apache Log4j
      • Jakarta Commons logging
    • 分散コンポーネント技術
      • EJB
    • リッチ クライアント
      • Java Web Start
    • GUI
    • XML Web サービス
      • Apache Axis
      • Apache SOAP
    • アプリケーション管理
    • トランザクション
    • 開発環境
      • Apache Ant
      • Apache Maven
      • Apache Maven2
    • Eclipse
    • Tips
  • .NET Framework
  • PHP
  • XML
    • SmartDoc
  • 正規表現
  • VB, VBA, VBScript, ASP
  • C/C++

DBMS


  • MySQL
  • PostgreSQL
  • Oracle
  • Microsoft SQL Server
  • HSQLDB
  • SQLite
  • Apache Xindice

アプリケーション サーバ



OS



バージョン管理システム



未整理


最近更新したページ
このウィキの読者になる
更新情報がメールで届きます。
このウィキの読者になる

.NET Tips/Delegate

デリゲートは、実行時にメソッドを参照する型です。関数ポインタのように使用することができます。

デリゲートは同期処理


デリゲートは同期処理です。つまり、デリゲートを呼び出すと、その処理が終了するまで次の処理に進めません。以下のサンプルでそのことを確認できます。

class SampleDelegate1
{
    public static void Main()
    {
        EventHandler e = new EventHandler(Foo);
        
        Console.WriteLine("event calling.");
        e(null, null);
        Console.WriteLine("event called.");
    }
    public static void Foo(object sender, EventArgs e)
    {
        Console.WriteLine("foo start.");
        Thread.Sleep(3000);
        Console.WriteLine("foo end.");
    }
}

このサンプルをコンパイルして実行すると、次の結果が得られます。

event calling.
foo start.
foo end.
event called.

もしデリゲートが非同期処理なら、 "foo start." から "foo end." の間で 3 秒間停止している間に "event called." が呼ばれるはずです (場合によるけれど) 。

マルチキャスト デリゲートも同期処理です。マルチキャスト デリゲートの場合、デリゲート変数に追加した順番にメソッドが呼ばれます。以下のサンプルでそのことを確認できます。

class SampleDelegate2
{
    public static void Main()
    {
        EventHandler e = new EventHandler(Foo);
        e += new EventHandler(Bar);
        e += new EventHandler(Boo);
        
        Console.WriteLine("event calling.");
        e(null, null);
        Console.WriteLine("event called.");
    }
    public static void Foo(object sender, EventArgs e)
    {
        Console.WriteLine("foo start.");
        Thread.Sleep(1000);
        Console.WriteLine("foo end.");
    }
    public static void Bar(object sender, EventArgs e)
    {
        Console.WriteLine("bar start.");
        Thread.Sleep(1000);
        Console.WriteLine("bar end.");
    }
    public static void Boo(object sender, EventArgs e)
    {
        Console.WriteLine("boo start.");
        Thread.Sleep(1000);
        Console.WriteLine("boo end.");
    }
}

このサンプルをコンパイルして実行すると、次の結果が得られます。

event calling.
foo start.
foo end.
bar start.
bar end.
boo start.
boo end.
event called.

デリゲートの例外処理


デリゲートとして呼び出したメソッドの処理で例外がスローされると、呼び出し元に例外がスローされます (まぁ、当たり前ですが) 。以下のサンプルでそのことを確認できます。

class SampleDelegate3
{
    public static void Main()
    {
        EventHandler e = new EventHandler(Foo);
        
        Console.WriteLine("event calling.");
        try
        {
            e(null, null);
        }
        catch (InvalidOperationException ex)
        {
            Console.WriteLine(ex);
        }
        Console.WriteLine("event called.");
    }
    public static void Foo(object sender, EventArgs e)
    {
        Console.WriteLine("foo start.");
        Thread.Sleep(1000);
        throw new InvalidOperationException();
    }
}

このサンプルをコンパイルして実行すると、次の結果が得られます。

event calling.
foo start.
System.InvalidOperationException: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。
   at SampleDelegate3.Foo(Object sender, EventArgs e)
   at SampleDelegate3.Main()
event called.

Foo メソッドをデリゲート変数に登録し、デリゲートとして呼び出します。 Foo メソッドは InvalidOperationException 例外をスローします。 InvalidOperationException 例外は Main メソッドでキャッチされ、コンソールに文字列表現が出力されます。その後、 "event called." がコンソールに表示されます。このことにより、デリゲート呼び出しでスローされた例外は、呼び出し元にスローされ、キャッチすることもできるといえます。

マルチキャスト デリゲートとして呼び出したメソッドの中で例外がスローされると、そのデリゲート呼び出しはそこで終了します。例えば、 Foo, Bar, Boo メソッドをマルチキャスト デリゲートとして呼び出して Bar メソッドが例外をスローした場合、 Boo メソッドは呼び出されません。以下のサンプルでそのことを確認できます。

event calling.
foo start.
foo end.
bar start.
System.InvalidOperationException: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。
   at SampleDelegate4.Bar(Object sender, EventArgs e)
   at System.EventHandler.Invoke(Object sender, EventArgs e)
   at SampleDelegate4.Main()
event called.

Bar メソッドの呼び出しで InvalidOperationException 例外がスローされますが、その後の Boo メソッドが呼び出されず、 "event called." が表示されていることが分かります。
2005年12月25日(日) 20:36:22 Modified by uguuxp




スマートフォン版で見る