Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

F#のクラスの拡張

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

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2010/04/01 14:00

 C#ではメソッドを拡張することができますが、F#でも同様にメソッドを拡張することができます。加えて、F#ではメソッドだけではなく、プロパティやイ ベントなどのメンバーを既存のクラス(type)に追加することができます。今回はこのクラスの拡張について解説したいと思います。

目次

はじめに

 C#ではメソッドを拡張することができますが、F#でも同様にメソッドを拡張することができます。加えて、F#ではメソッドだけではなく、プロパティやイベントなどのメンバーを既存のクラス(type)に追加することができます。今回はこのクラスの拡張について解説したいと思います。

クラスの拡張

 F#のモジュールは複数のファイルにまたがることができません。しかし、このクラスの拡張を使用することで、長い1つのファイルを作成することなく各メンバーを記述することが可能になります。

[構文]クラスの拡張
//組み込み拡張
    type クラス名 with
        member セルフ識別子.メンバー名 =
        本体
   ...
   [ end ]

//オプショナル拡張
module モジュール名 = 
    type 完全修飾クラス名 with
           member セルフ識別子.メンバー名 =
           本体
   ...
   [ end ]

 クラスの拡張には2種類あり、1つは組み込み拡張と呼ばれ、拡張されるクラスと同一名前空間、同一モジュール、同一ソースファイル、同一アセンブリ内に記述される拡張です。もう1つはオプショナル拡張と呼ばれ、拡張されるクラスのモジュール、名前空間、もしくはアセンブリの外で表されます。

 オプショナル拡張はモジュール内で定義される必要があり、使用するためにはそのモジュールをopenで読み込む必要があります。組み込み拡張はクラスがリフレクションによって分析されてからクラスに現れるようになります。

メソッドの拡張

 C#同様に、F#はメソッド拡張をサポートします。C#とは構文が違うだけではなく、F#のクラス拡張はインスタンスメンバーにも、静的(static)メンバーにも適用できます。

 C#3.0で導入された拡張メソッドとF#におけるメソッドの拡張方法を比較してみたいと思います。

 例として、System.Stringクラスに値がNULL(もしくは空)かどうか判断させるメソッドIsNullorEmpを追加してみましょう。

[リスト1]C#による拡張メソッド
using System;
using testNSA;  //※2 拡張メソッドが定義された名前空間をスコープに入れる

//拡張メソッドの定義
namespace testNSA
{
    public static class testExt  //メソッド拡張用にクラスを作成
    {
        public static bool IsNullorEmp(this string s) //※1 拡張メソッド定義部分。拡張されるクラスをパラメータとしてthisの後に記述
        {                                                     
            return (s == null || s.Length == 0);
        }
    }
}

namespace testNSB
{
    class Program
    {
        static void Main(string[] args)
        {
            string testStr = null; //※3 System.Stringクラスのインスタンス作成
            if (testStr.IsNullorEmp ())  //※4 拡張したメソッドを呼び出す
            {
                Console.WriteLine("NULLか空です。");
            }
        }
    }
}

 まずはじめに、C#の例を見てください。メソッド拡張を定義する名前空間testNSAに追加するメソッドとその仕様を定義しています(※1)。そして、その拡張メソッドを定義した名前空間(リスト1ではtestNSA)をusingでスコープに入れる(※2)ことで、System.Stringクラスのインスタンス(※3)は新しく追加されたメソッドを呼び出す(※4)ことができるようになります。

 では、これをF#で行ってみましょう。

[リスト2]F#による拡張メソッド
open System

type String with //※1 System 名前空間をスコープに取り込んでない場合は、System.Stringに。
    member this.IsNullorEmp() =  //※2 追加するメソッド
        (this = null || this.Length = 0)  //※3

let a = string(null);;  //※4 テスト用インスタンス作成
if( a.IsNullorEmp()) then Console.WriteLine("NULLか空です。");;  //※5

 ▼

type String with

  member IsNullorEmp : unit -> bool

val a : string = ""


> NULLか空です。

val it : unit = ()

 System.String(クラス)に値がNull(もしくは空)かどうかを判断するメソッドを追加するF#のオプショナル拡張の例です。

 typeの後ろにメソッド拡張するクラスを指定し(※1 この場合System.String)、その後に追加するメンバー(メソッド)を定義(※2)します。thisはセルフ修飾子ですので、任意の文字を入れてください。セルフ修飾子の後のドットに続き、メンバー名を指定して、メソッドの仕様を定義します。メソッドを拡張するために新たなクラスを作成する必要がありません。

 リストの例では、IsNullorEmpメソッドはパラメータがnullもしくは長さが0の場合に、trueを返します(※3)。後半2行でこの追加されたメソッドを実際に呼び出しています。String型のインスタンスaを作成(※4)すると、a経由で追加されたメソッドを呼び出すことが可能であることが確認できます。ifを用いた条件文で、a.IsNullorEmpがtrueの場合に「NULLです。」と表示させるよう定義(※5)してます。

 Stringクラスにこのメソッドが追加されたかどうかは、下記のようにインテリセンスのステートメントの入力候補としてそのメソッドが表示されることによっても確認することができます。

インテリセンスの入力候補に新しいメソッドが追加されている
インテリセンスの入力候補に新しいメソッドが追加されている

 例で使用した、if文(条件式)の構文は以下のようになります。

[構文]if文(条件式)
if条件式 then式1 [ else 式2 ]

 条件式がtrueの場合式1を実行し、falseの場合はelse以降を実行します。


  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

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

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

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

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

バックナンバー

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

もっと読む

All contents copyright © 2005-2018 Shoeisha Co., Ltd. All rights reserved. ver.1.5