Getting a Good Grasp of F# (仮)

関数型言語F#をもっと楽しみたい

F# クラスのプロパティ定義をシンプルに記述する

メンバとして public なプロパティ Namestring 型、読み書き可)を持つ単純なクラス Person1C# と F# 双方で定義してみます。

  • [注意] F# のクラスのアクセシビリティはデフォルトで public です。同様に、メソッドやプロパティもアクセシビリティはデフォルトで public です。ただしクラス内でlet束縛された値は  privateです。
C# と F# でクラス宣言のコード比較
public class Person1
{
    private string _name = "Tom";
    public string Name
    {
        get { return _name; }
        set { _name = value; }
    }
}
type Person1() =
    let mutable _name = "Tom"
    member __.Name  
        with get(): string = _name
        and set (v: string) = _name <- v

 

C# では自動実装プロパティ(Auto-Implemented Properties)の文法があるので上記のようなプロパティの定義を意味を変えずに以下のようにシンプルに記述できます。

class Person2
{
    public string Name { get; set; } = "John";
}

 

F# でも同様にシンプルな記述に変えることができます。

type Person2() =
    member val Name: string = "John" with get, set

 

ここで、プロパティの getter / setter のアクセシビリティをそれぞれ別のものを指定する(以下のコードでは getter は public に、 setter は privateにそれぞれ指定)場合を考えてみます。

C# では以下のようにシンプルに記述できますが、

public class Person3
{
    public string Name { get; private set; } = "Alice";
}

 

こういう場合、F# ではどうしても冗長な書き方をするしかありませんが、 getter / setter それぞれのアクセシビリティを個別に指定することはできます。

type Person3() =
    let mutable _name = "Alice"
    member __.Name  
        with get(): string = _name
        and private set (v: string) = _name <- v

 

また、プロパティの getter / setter は以下のように分けて定義することもできます。

type Person3'() =
    let mutable _name = "Jane"
    member __.Name  with get(): string = _name
    member __.Name  with private set (v: string) = _name <- v