デリゲート (プログラミング)

デリゲート (: delegate) とは、主にC#Visual Basic .NETなどの、.NET環境向けのプログラミング言語(.NET言語)に用意されている機能であり、参照型の一種(デリゲート型)である。

概要

デリゲートは、オブジェクトインスタンスへの参照とメソッドへの参照をペアにしてカプセル化するものである。概念としてはC言語C++関数ポインタに近いが、デリゲートは完全なオブジェクト指向である[1]型安全であるという特徴がある[2]。2002年にリリースされた.NET FrameworkではSystem.Delegateクラス[3]が定義されており、このクラスおよび派生クラスを簡潔に利用するための各種構文が.NET言語に導入された。

Object PascalDelphi)の「インスタンスのメソッドへのポインタを格納する、メソッドポインタ」と同様のものである。また、Microsoft Visual J++も、Javaと非互換のデリゲートを導入したが、.NET Frameworkのデリゲートはこれらを発展させたものである[注釈 1]

なお、C++における「クラスの非静的メンバ関数を指す関数ポインタ」は、関数呼び出し時にそのクラスのインスタンスを必要とする。デリゲートのようにオブジェクトとして扱うためにはstd::functionなどの関数オブジェクトによるカプセル化が必要となる。

デリゲートにより、メソッド単位のコンポジション (合成) が可能となる。デリゲートは主に、イベント処理での活用(コールバック処理のカスタマイズ)を想定している。Javaなどでのインターフェイスを利用したイベント処理と比べ、デリゲートによって参照されるメソッド(実体)の名前を自由に宣言できる、振る舞いをカスタマイズするために(明示的な)インターフェイスの実装やスーパークラスの継承を行なう必要がない(新たにクラスをわざわざ定義しなくてよい[注釈 2])、などの利点がある。

C#では複数のデリゲートを+, -, +=, -=演算子によって結合・分離させることもできる(マルチキャストデリゲート[4])。また、デリゲートの追加・削除と呼び出しに制約を加えて安全なコードを記述するための機構としてeventキーワードが用意されている[5] [6]eventキーワードで修飾されたデリゲート型メンバーに、外部からイベントのサブスクリプション(購読)を追加・削除する手段としては、+=演算子および-=演算子によるアクセスのみが許可される。また、eventキーワードで修飾されたデリゲート型メンバーを、クラス外部からメソッドとして呼び出すことはできない。なお、+=演算子および-=演算子の処理をカスタマイズするために、eventキーワードで修飾されたデリゲート型メンバーのaddアクセッサーとremoveアクセッサーを明示的に記述することも可能である。

そのほか、スレッドプールを利用して非同期でデリゲートを実行する機能も存在する(非同期デリゲート[7])。

Visual J++

参考

C#

C#の例を示す。まず以下では、「string型の引数を1つと、int型の戻り値を持つデリゲート」を宣言している。

delegate int SomeDelegate(string p);

コンパイラによって、System.Delegateから派生するSomeDelegate型が生成される。

次に、以下のようなメソッドを持つクラスがあったとする。

class SomeClass
{
  private string someField = "TEST:";
  public int SomeMethod(string p)
  {
    return this.someField.Length + p.Length;
  }
  public static int SomeStaticMethod(string p)
  {
    return p.Length;
  }
}

そして、以下のように(デリゲートと同じ引数と戻り値を持つ)既存の名前付きメソッドを参照するデリゲート型オブジェクトを生成することができる。

SomeDelegate del = new SomeDelegate(SomeClass.SomeStaticMethod);

C/C++の関数ポインタと異なり、静的メソッドだけでなくインスタンスメソッドをデリゲートに代入することもできる(メソッドとインスタンスのペアがカプセル化される)。

SomeClass obj = new SomeClass();
SomeDelegate del = new SomeDelegate(obj.SomeMethod);

C# 2.0以降では、匿名メソッド (anonymous method) としてインラインで記述したメソッドを参照するデリゲートを同時に定義することもできる。この書き方では、return文によって返される値がSomeDelegateデリゲートの戻り値に暗黙的に変換できない場合、エラーとなる。

SomeDelegate del = new SomeDelegate(delegate(string p) {
  return p.Length;
});

なおC# 3.0以降では、匿名メソッドの代わりにラムダ式を使って下記のように記述することもできる。

SomeDelegate del = (p) => {
  return p.Length;
};

匿名メソッドとラムダ式は併せて匿名関数 (anonymous function) と呼ばれる。匿名関数は外側の変数にアクセスすることができ、これをキャプチャと呼ぶ。匿名関数とデリゲートを用いてクロージャを実現することができる。

こうして生成したデリゲート型オブジェクトは、通常のメソッドのように直接実行することができる。

int ret = del("some string");

なお、上記は以下のInvokeメソッド呼び出しに対する糖衣構文である。Invokeメソッドはコンパイラによって自動生成される。

int ret = del.Invoke("some string");

しかし、デリゲートの真価が発揮されるのはイベントと併用した時である。イベントは、次のように宣言する。

class MyClass
{
  public event SomeDelegate SomeEvent;
}

こうして宣言したイベントには、+= 演算子と -= 演算子によって、デリゲート(イベントハンドラ)を追加したり削除したりすることができる。

MyClass obj = new MyClass();
obj.SomeEvent += new SomeDelegate(SomeEventHandler1);
obj.SomeEvent -= new SomeDelegate(SomeEventHandler1);
//obj.SomeEvent = new SomeDelegate(SomeEventHandler1); // 外部からの再代入はできないのでコンパイルエラー。
//obj.SomeEvent(); // 外部からの呼び出しはできないのでコンパイルエラー。

イベントハンドラの追加が += 演算子によって行われることから推測できるように、1つのイベントには複数のイベントハンドラを登録することができる。

次のようにしてイベントの定義されたクラスの内部からイベントを起こすと、登録したイベントハンドラがまとめて実行される。

class MyClass
{
  void ExecuteEventHandlers()
  {
    if (SomeEvent != null)
      SomeEvent("some string");
  }
}

実行される順番は登録順とは関係なく、未定義である。

なお、eventで修飾されていない通常のデリゲート型メンバーと異なり、SomeEventにはクラス外部から=演算子で直接再代入をすることはできない。また、SomeEventが定義されたクラス内からしか呼び出せない。この制約により、誤ってイベントサブスクリプションをクリアしてしまうことを防止したり、イベントハンドラーを呼び出す責任の所在を明確にしたりすることができる。

P/Invokeとデリゲート

プラットフォーム呼び出し(P/Invoke)の際は、デリゲートは既定でアンマネージ(ネイティブ)の関数ポインタにマーシャリングされる[8]

例えば下記のようなC言語関数がMyLibrary.DLLに実装されているとする。

typedef BOOL (__stdcall*TMyCallbackFuncPtr)(LPCWSTR fileName);

/* カレントディレクトリのファイルを列挙する関数。ファイルが見つかるごとにコールバック関数が呼ばれる。 */
extern __declspec(dllexport) BOOL EnumFiles(TMyCallbackFuncPtr callback);

対応するP/Invokeラッパーインターフェイスおよび呼び出しの一例は下記のようになる。

using System;
using System.Runtime.InteropServices;

static class MyPInvoker
{
    public delegate bool MyCallbackDelegate([In, MarshalAs(UnmanagedType.LPWStr)]string fileName);

    [DllImport("MyLibrary.dll")]
    public extern static bool EnumFiles(MyCallbackDelegate callback);

    private static bool MyCallbackMethod(string fileName)
    {
        Console.WriteLine(fileName);
        return true; // 列挙を続行。
    }

    private static void Test()
    {
        EnumFiles(MyCallbackMethod);
    }
}

P/Invokeでデリゲートを渡す場合は、デリゲート型のインスタンスがガベージコレクションにより回収されてしまわないように注意する必要がある[9][10]。また、コールバック関数の呼び出し規約が一致するようにしなければならない(.NET 1.1まではstdcall呼び出し規約のみが使用可能だったが、.NET 2.0以降ではUnmanagedFunctionPointerAttribute属性を明示的に指定することでcdecl呼び出し規約を使用することも可能である[11])。

その他の言語のデリゲート

D言語には関数オブジェクトがあり、型としてfunctionとdelegateがある。無名関数を作る式として関数リテラルがあり、functionとdelegateのそれぞれに対応した構文がある。関数リテラルの省略構文としてラムダ式がある。functionとdelegateの違いは、作られたスコープの環境にアクセスできるかどうかで、アクセスする場合はデリゲートである必要がある。ラムダ式では内容に応じて、デリゲートである必要がある場合はデリゲートになる。

Javaはバージョン8にてラムダ式とともにメソッド参照の機能を導入した。ただしマルチキャストデリゲートに相当する機能はない。

C++/CLIは.NETマネージ言語であり、.NETのデリゲートをサポートする。メソッド宣言にdelegateキーワードを使用することで、System::MulticastDelegateを継承した、Invokeという名前のメソッドを持つクラスが自動定義される点などは、C#とほぼ同じである[12]。ただし、C++11で追加されたラムダ式を使ってデリゲートのインスタンスを生成することはできず、gcnewを使って明示的にデリゲートのインスタンスを生成する必要があるため、C# 2.0以降と比較してコードが煩雑になる[13]

C++/CX英語版は.NETマネージ言語ではなくネイティブ言語拡張だが、デリゲートをサポートする。イベントハンドラーの割り当てに利用される。ただし、C++/CXは参照カウントベースのガベージコレクションを採用していることから、強い参照による循環参照を防ぐため、イベントハンドラーの記述にはラムダ式よりも名前付き関数を利用することが推奨されている[14]

Objective-Cは言語機能としてデリゲートを持たないが、Objective-Cを用いたイベント駆動型ソフトウェアを開発する際の基本的なデザインパターンとして「委譲」が採用されている[15]。実態はJavaのインターフェイスを利用したイベントコールバックと同じく、XxxDelegateという名前を持つプロトコル(抽象型の一種)を採用(adopt)することでイベント処理のカスタマイズを実現する。Swiftのデリゲートも同様である。

脚注

注釈

  1. ^ DelphiもJ++もC#もアンダース・ヘルスバーグによる設計である。
  2. ^ Javaではまずinterface構文によるインターフェイスやclass構文によるスーパークラスの定義が必要であり、コード量が膨れ上がりやすい。サブクラス(インターフェイス実装クラス)の記述に関しては、無名クラスやラムダ式を利用することで簡略化できるが、コンパイラによって新たにサブクラス(インターフェイス実装クラス)が定義されることに変わりはない。

出典

関連項目

Read other articles:

يفتقر محتوى هذه المقالة إلى الاستشهاد بمصادر. فضلاً، ساهم في تطوير هذه المقالة من خلال إضافة مصادر موثوق بها. أي معلومات غير موثقة يمكن التشكيك بها وإزالتها. (أكتوبر 2023)   لمعانٍ أخرى، طالع وزارة الموارد المائية (توضيح). وزارة الري تفاصيل الوكالة الحكومية البلد الجزائر&...

 

The list of ship launches in 1747 includes a chronological list of some ships launched in 1747. Date Country Builder Location Ship Class Notes 21 January  Great Britain Earlsman Sparrow Rotherhithe Queenborough Sixth rate For Royal Navy.[1] 4 February Ottoman Empire Constantinople Perr-i Bahri Fifth rate For Ottoman Navy.[2] 12 February  Kingdom of France Joseph Veronique Charles Chapelle Toulon Le Content Third rate For French Navy.[3] 23 February Republic o...

 

الانتخابات البرلمانية السورية 2016  →2012 13 أبريل 2016 2020←  جميع المقاعد 250 لمجلس الشعب السوريالمقاعد اللازمة للأغلبية 126   الحزب الأول   القائد بشار الأسد الحزب حزب البعث التحالف الجبهة الوطنية التقدمية آخر انتخاب 168 المقاعد المربوحة 200 تغيّر المقعد 32 الرئيس قب

BTN beralih ke halaman ini. Untuk kegunaan lain, lihat BTN (disambiguasi). Artikel ini berisi konten yang ditulis dengan gaya sebuah iklan. Bantulah memperbaiki artikel ini dengan menghapus konten yang dianggap sebagai spam dan pranala luar yang tidak sesuai, dan tambahkan konten ensiklopedis yang ditulis dari sudut pandang netral dan sesuai dengan kebijakan Wikipedia. PT Bank Tabungan Negara (Persero) TbkMenara BTN (kanan)JenisBadan usaha milik negaraKode emitenIDX: BBTNIndustriJasa keuangan...

 

Suburb of Sydney, New South Wales, AustraliaClontarfSydney, New South WalesClontarfPopulation1,737 (2016 census)[1] • Density2,170/km2 (5,600/sq mi)Postcode(s)2093Elevation20 m (66 ft)Area0.8 km2 (0.3 sq mi)Location13 km (8 mi) north-east of Sydney CBDLGA(s)Northern Beaches CouncilState electorate(s)ManlyFederal division(s)Warringah Suburbs around Clontarf: Seaforth Balgowlah Seaforth Seaforth Clontarf Balgowlah Heights Mosman M...

 

Sun Plaats in de Verenigde Staten Vlag van Verenigde Staten Locatie van Sun in Louisiana Locatie van Louisiana in de VS Situering Parish St. Tammany Parish Type plaats Village Staat Louisiana Coördinaten 30° 39′ NB, 89° 54′ WL Algemeen Oppervlakte 11,2 km² - land 10,8 km² - water 0,4 km² Inwoners (2006) 498 Hoogte 21 m Overig FIPS-code 73955 Portaal    Verenigde Staten Sun is een plaats (village) in de Amerikaanse staat Louisiana, en valt bestuurlijk gezien onder S...

1929年菲律賓颱風形成1929年8月31日消散1929年9月6日最低氣壓954.62百帕(毫巴);28.19英寸汞柱 死亡120人死亡210人失踪損失> $80萬(1929年美元)影響地區美屬菲律賓中華民國 1929年9月初,一場颱風在菲律賓造成嚴重災害[1]。共造成120人死亡,210人失踪。 参考资料 ^ Typhoon Deaths in Philippines Mount to 200; Thousands Homeless After Catastrophe. The New York Times. 1929-09-09 [2021-04-22]. ISSN&#...

 

هذه المقالة يتيمة إذ تصل إليها مقالات أخرى قليلة جدًا. فضلًا، ساعد بإضافة وصلة إليها في مقالات متعلقة بها. (سبتمبر 2018) أنطون تشيشولين معلومات شخصية الميلاد 27 نوفمبر 1984 (39 سنة)  أستانا  الطول 1.82 م (5 قدم 11 1⁄2 بوصة) مركز اللعب وسط الجنسية كازاخستان  المسيرة ا...

 

  لمعانٍ أخرى، طالع ريال (توضيح). ريال سوسيداد اللقب Txuri-Urdinak (البيض والزرق) La Real (الملكي) الاسم المختصر سوسيداد تأسس عام 1909 (منذ 114 سنة) الملعب ملعب أنويتا(السعة: 39,500) البلد  إسبانيا الدوري لا ليغا الإدارة المدرب إيمانول ألغاوسيل الموقع الرسمي www.realsociedad.eus بعض التاريخ اللا

2001 video game 2001 video gameFinal Fantasy XNorth American cover art featuring the protagonist TidusDeveloper(s)Square Product Development Division 1Publisher(s)JP: SquareNA: Square Electronic ArtsPAL: Sony Computer EntertainmentDirector(s)Yoshinori KitaseProducer(s)Yoshinori KitaseDesigner(s) Motomu Toriyama Takayoshi Nakazato Toshiro Tsuchida Programmer(s) Koji Sugimoto Takashi Katano Artist(s) Yusuke Naora Shintaro Takai Tetsuya Nomura Writer(s) Kazushige Nojima Daisuke Watanabe Motomu T...

 

Bisporella Bisporella citrina pada sebuah kayu Klasifikasi ilmiah Kerajaan: Fungi Divisi: Ascomycota Subdivisi: Pezizomycotina Kelas: Leotiomycetes Ordo: Helotiales Famili: Helotiaceae Genus: BisporellaSacc. (1884) Spesies tipe Bisporella monilifera(Fuckel) Sacc. (1884) Sinonim[1] Bispora Fuckel (1870) Calycella Quél. (1886) Bisporella adalah genus jamur dalam famili Helotiaceae. Per Februari 2015, basis data nomenklatural Index Fungorum menuliskan 26 spesies dalam genus ini.[2&#...

 

2011 film by David Mackenzie This article is about the film. For the unrelated song by Roger Waters, see Perfect Sense (song). Perfect SenseUK theatrical posterDirected byDavid MackenzieWritten byKim Fupz AakesonProduced by Malte Grunert Gillian Berrie Starring Eva Green Ewan McGregor Ewen Bremner Stephen Dillane Connie Nielsen CinematographyGiles NuttgensEdited byJake RobertsMusic byMax RichterProductioncompaniesTrustNordiskBBC FilmsZentropa EntertainmentScottish ScreenDanish Film InstituteF...

Blue Chip Blue chip adalah sebuah istilah dalam pasar modal yang mengacu pada saham dari perusahaan besar yang memiliki pendapatan stabil dan liabilitas dalam jumlah yang tidak terlalu banyak. Istilah ini berasal dari istilah di kasino, di mana blue chips mengacu pada chip yang memiliki nilai paling besar. Saham blue chip biasanya memberikan dividen secara reguler, bahkan ketika bisnis berjalan lebih buruk dari biasanya. Referensi Artikel bertopik keuangan, uang, atau mata uang ini adalah seb...

 

Airport in Nepal This article is about the international airport in Pokhara, Nepal. For the domestic airport in Pokhara, see Pokhara Airport. Pokhara International Airportपोखरा अन्तर्राष्ट्रिय विमानस्थलIATA: PKRICAO: VNPR[1]SummaryAirport typePublicOwnerGovernment of NepalOperatorCivil Aviation Authority of NepalServesPokharaLocationPokhara, Gandaki Province, NepalOpened1 January 2023; 11 months ago (2023-01-0...

 

Non-fiction book written by Michael W. Twitty The Cooking Gene: A Journey through African American Culinary History in the Old South AuthorMichael W. TwittyCountryUnited StatesLanguageEnglishGenreMemoirPublished2017 (HarperCollins Publishers)ISBN9780062379290 The Cooking Gene: A Journey Through African American Culinary History in the Old South is an American non-fiction book written by Michael W. Twitty. It was published in 2017 and is a food memoir. The author combines intensive genealogica...

Mohammad Kazem ShariatmadariShariatmadari, Maret 1982GelarAyatollah AgungInformasi pribadiLahir5 Januari 1906Tabriz, PersiaMeninggal3 April 1986(1986-04-03) (umur 80)Tehran, IranAgamaIslamEtnisAzeriZamanSejarah modernKredoIslam Syiah Dua Belas Imam Usuli Sayyid Mohammad Kazem Shariatmadari (Persia: محمد کاظم شریعتمداری), juga disebut Shariat-Madari (5 Januari 1906 – 3 April 1986), adalah seorang Ayatollah Agung Iran. Ia menyukai praktek Syiah tradisi...

 

New York City-based pop rock band This article is an orphan, as no other articles link to it. Please introduce links to this page from related articles; try the Find link tool for suggestions. (February 2018) The Vitamen were an unsigned three-piece pop rock band from New York City. The band's three members were frontman Jesse Blockton, bassist Matt Hyams, and drummer Dave Rozner, all of whom attended the same high school in Mamaroneck, New York.[1] Their debut album, Fun, was release...

 

Galaksi Andromeda yang berjarak sekitar 2,5 juta tahun cahaya dari Bima sakti yang dibatasi oleh ruang antargalaksi. Ruang antargalaksi (Inggris: Intergalactic Space) adalah wilayah ruang fisik yang ada di antara galaksi.[1] Umumnya bebas dari debu dan kotoran, ruang antargalaksi sangat dekat dengan ruang hampa udara absolut. Hanya ada sedikit debu dan puing, para ilmuwan telah menghitung bahwa mungkin hanya ada satu atom hidrogen per meter kubik. Kepadatan material lebih tinggi di de...

2005 American filmThe Godfather of Green BayPromotional movie posterDirected byPete SchwabaWritten byPete SchwabaProduced byPete SchwabaBrian R. EttingStarringPete SchwabaLance BarberLauren HollyRelease date 2005 (2005) Running time90 minutesCountryUnited StatesLanguageEnglish The Godfather of Green Bay is a fictional comedic movie released in 2005. It follows the tale of stand-up comedian Joe Keegan (played by Pete Schwaba). Joe makes a last-ditch effort to save his career by traveling ...

 

Species of mammal RakaliTemporal range: Holocene Conservation status Least Concern (IUCN 3.1)[1] Scientific classification Domain: Eukaryota Kingdom: Animalia Phylum: Chordata Class: Mammalia Order: Rodentia Family: Muridae Genus: Hydromys Species: H. chrysogaster Binomial name Hydromys chrysogasterGeoffroy, 1804 Distribution of the rakali The rakali (Hydromys chrysogaster), also known as the rabe, the Australian Otter or water-rat, is an Australian native rodent first scien...

 

Strategi Solo vs Squad di Free Fire: Cara Menang Mudah!