F# クラスのプロパティ定義をシンプルに記述する
メンバとして public
なプロパティ Name
(string
型、読み書き可)を持つ単純なクラス Person1
を C# と 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