SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

C#プログラマのためのF#入門

F#のクラスの拡張

C#プログラマのためのF#入門(5)

  • X ポスト
  • このエントリーをはてなブックマークに追加

(3)イベントの拡張

 メソッド、プロパティ同様にイベントによるクラス拡張も以下の構文を用いて行うことが可能です。

[構文]イベントによるクラス拡張
let 組名 = new Event<_>() 
type 拡張クラス名 with
    member イベント定義

 リスト7はSystem.Stringにイベントを追加し拡張する例です。

[リスト7]イベントのクラス拡張
open System.Windows.Forms

let event = new Event<_>() //※1
type System.String with //※2 System.Stringの拡張
    member this.testEvent() = 
        Event.add(fun str -> printfn "%s" str) event.Publish //※3 
    member this.testTrigger(a) =  //※4 トリガー定義
        event.Trigger(a)

//※5 イベント呼び出し
let testIns = System.String(null)
testIns.testEvent()
testIns.testTrigger("aaaa")

 ▼

aaaa

val event : Event<string>
type String with
  member testEvent : unit -> unit
type String with
  member testTrigger : a:string -> unit
val testIns : System.String = ""

 まず、new Eventで組を作成(※1)し、続いて拡張するクラスを指定(※2)します。

 イベントハンドラとして、渡された引数を表示するラムダ式を追加しイベントを発行(※3)します。通常のイベントの新規作成と同様に、イベントトリガーもmemberとして定義(※4)します。

 イベントがSystem.Stringクラスに追加され、String型のインスタンス経由でイベントを呼ぶ(※5)ことができるようになります。

 ある種の機能が不可なものよりは可のほうが柔軟な言語とは言えるかもしれませんが、残念ながら正直、どういったシチュエーションでイベント拡張を利用すると効果的なのか作者には使いどころが思い当たりません。

(4)デリゲート(委譲)

 関数が第一級(ファーストクラス)オブジェクトのF#においては関数をパラメータなどの値として表すことが可能ですが、その他の.NETフレームワークのAPIと相互運用する場合には、デリゲートを使用します。

[リスト8]C#でのデリゲート使用例
    delegate int testDel(int x, int y); //デリゲート宣言
    class testClass
    {
        public int testMethod(int x, int y)  //※1
        {
            return x * y;
        }
    }
    class Class1
    {
        [STAThread]
        static void Main(string[] args)
        {
            testClass instance = new testClass();
            testDel testIns = new testDel(instance.testMethod);  // testMethodを委譲
            Console.WriteLine(testIns(5, 10));  //(※2)デリゲート型のインスタンス経由で呼び出し
        }
    }

 引数を2つ受け取るtestMethod(※1)を呼び出すために、デリゲート型testDelのインスタンス経由でパラメータを渡し(※2)、メソッドtestMethodを呼び出しています。

 F#のデリゲートの使用方法はC#のそれと大変似ています。

[構文]デリゲート
type デリゲート名 = delegate of引数の型 -> 戻り値の型

 上記のC#の例はF#では以下のようになります。

[リスト9]F#でのデリゲート使用例
type testdel = delegate of (int*int) -> int  //デリゲート宣言
let a = new testdel(fun (x, y) -> x * y)  //※1 ラムダ式を委譲
Console.WriteLine(a.Invoke(5, 10));;  // ※2 Invokeメソッド経由で呼び出し

 ▼

50

type testdel =
  delegate of (int * int) -> int 
val a : testdel

 ラムダ式を用いると若干すっきりしますね。

 デリゲートの宣言はC#と非常に似ていますが、delegateに委譲したラムダ式(※1)を呼ぶ際には、Invokeメソッドを使用(※2)します。

 残念ながら、現時点では拡張されたプロパティやイベントにはF#プログラムからのみアクセスできるようです。

まとめ

 今回はクラスの拡張機能について解説しました。新たな継承クラスを作成したり、クラスへの変更なしに様々なオブジェクトが拡張できる機能を使ってより効率的なコーディングをしてください。次回はF#のオブジェクト指向の最終回としてオブジェクト式について解説したいと思います。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
C#プログラマのためのF#入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 星山 仁美(ホシヤマ ヒトミ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/4990 2010/04/01 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング