プロパティとは
クラスと構造体で定義できる特殊なメソッド。
クラスや構造体のデータを保持する変数であるフィールドに安全にアクセスするために作成する。
プロパティを介することで、オブジェクトに認識されないまま不意に外部のコードから値を変更されるのを防ぐ効果がある。
フィールドをprivateで定義し、プロパティをpublicで定義することで、プロパティを介してのみフィールドを読み書きすることを強制することができる。
プロパティは、値を取得するためのgetアクセサー、値を設定するためのsetアクセサーを持っている。(getしかない場合もある。また、C#9.0からはinitアクセサーも追加されている。)
プロパティについての基本的な事項は以下の記事でも紹介している。
プロパティの定義方法
基本
フィールドをprivateで実装し、フィールドの値の読み書きのためにpublicなプロパティを追加。
コードスニペット propfull でフィールド~プロパティを簡単に入力できる。
setアクセサーのみのプロパティ(書き込み専用)も書くことができるが、それが必要になるケースはほとんどなく、あったとしても設計に問題があると考えるべきである。
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Class1 { //基本 private int _x; public int X { get { return _x; } set { _x = value; } } } |
自動実装プロパティ
通常、この書き方がよく使われる。
隠されたフィールドがコンパイラによって自動的に作成されている。ただし、このフィールドにはプログラマーが直接アクセスすることはできない。
setのみの自動実装プロパティは定義できない。
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Class2 { //自動実装プロパティ public int X { get; set; } //読み書き可能 public int Y { get; } //get-only(読み取り専用)…コンストラクタとプロパティ初期化子以外での値の設定不可 public int Z { get; private set; } //クラスの内部でのみ値の設定可 public int W { get; init; } //初期化時のみ値の設定可(get-only+オブジェクト初期化子、with式、他のinit内) } |
プロパティ初期化子の使用
C#6.0から、自動実装プロパティに初期化子を書くことができる。
初期化の順序は、初期化子→コンストラクタとなる。
そのため、コンストラクタで初期値を設定すると、初期化子の値が上書きされる。
1 2 3 4 5 6 7 8 9 10 11 12 |
public class Class3 { //プロパティ初期化子を使用(初期化子→コンストラクタの順に値を設定) public int X { get; set; } = 10; public int Y { get; } = 20; public int Z { get; private set; } = 30; public int W { get; init; } = 40; } |
式形式メンバ構文
C#6.0からはラムダ式を使って簡潔にプロパティを書けるようになった。
自動実装プロパティでは、読み取り専用(get-only)プロパティに限ってラムダ式で記述することができる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
public class Class4 { //式形式メンバ構文 private int _x; public int X { get => _x; set => _x = value; } //自動実装プロパティで式形式構文を使う(読み取り専用のみ) public int Y => _x * 20; } |
コメント