ホームに戻る
出典 :
関連 :
目次 :
プロパティ(property)とは
クラス外部に対してはフィールド(メンバ変数)のように振舞い、クラス内部に対してはメソッドのように振舞うもの。
オブジェクト指向プログラミングではフィールドに対する外部からの不用意なアクセスと、それによる改変を防ぐためにフィールドの実体を隠蔽し、
参照や更新の際には公開メソッドを用いること(カプセル化)が推奨されているが、
C++やJavaではフィールド(メンバ変数)と、それらに関連づく参照(get)・更新(set)メソッド(アクセサ)を体系的に管理することができなかった。
C#ではプロパティが導入され、クラス外にはフィールドに直接アクセスするような簡便なインタフェースを提供できるとともに、
フィールドとアクセサを包括的に管理できるようになっている。
プロパティがサポートされない言語(C++)の例
class C_TestClass
{
private:
int hp; //< メンバ変数 hp
public:
int getHp() { return hp; } //< 変数 hp の get アクセサ(getter)
void setHp(int x) { hp = x; } //< 変数 hp の set アクセサ(setter)
}
メンバ変数 hp を取得・更新する場合は getHp() 、setHp() を関数として呼ぶ必要がある。
C#でプロパティを用いた場合の例
class C_TestClass
{
private int hp; //< フィールド hp
// hp にアクセスするためのプロパティ
public int Hp
{
get { return hp; } //< getter
set { hp = value; } //< setter ( value には代入される値が格納される)
}
}
プロパティ Hp は公開フィールドのようにアクセスすることができる。
プロパティに対する代入が行われた( set が呼ばれた)場合、右辺値は value に格納される。
get / set いずれかのみの定義も可能(読み取り / 更新専用プロパティ)。
ここで、get のみを定義した場合は readonly と等価であり、コンストラクタ以外で値を書き換えることは不可能となる。
自動プロパティ
C# 3.0からは、単に値を読み書きする場合の記述を省略できるようになった。
class C_TestClass
{
// 自動プロパティ Hp
public int Hp { get; set; }
}
前節の例と意味的には等価である(フィールドが暗黙的に生成される)。ここでも同様に、get / set いずれかのみの定義も可能。
フィールドを明示的に宣言する必要が無く、管理が簡便となる。
添字付きプロパティ
添字アクセスを行う配列、またはコレクション要素もプロパティ化することができる。
インデクサーとは異なる。
コード例
// 配列要素を含むサンプルクラス
public class SampleData
{
private int _Size = 2;
// 配列型のフィールド _ArrayData
private int[] _ArrayData;
// _ArrayData を操作するプロパティ ArrayData
public int[] ArrayData
{
set { _ArrayData = value; }
get { return _ArrayData; }
}
// コンストラクタ
public SampleData()
{
// _ArrayData の初期化
_ArrayData = new int[_Size];
}
}
:
{
// SampleData のテスト用メソッド
void DoSomething()
{
// SampleData 型オブジェクト生成
SampleData sampleData = new SampleData();
// 添字付きプロパティを用いて値を書き込み
sampleData.ArrayData[0] = 32;
sampleData.ArrayData[1] = 34;
// 添字付きプロパティを用いて値を読み出し
Console.WriteLine(sampleData.ArrayData[0]);
Console.WriteLine(sampleData.ArrayData[1]);
}
}
実行結果
32
34
プロパティの get / set それぞれに異なるアクセス制限を設定
C# 2.0以降、get と set で異なるアクセスレベルを設定できるようになった。
注意が必要な点として、プロパティ全体に設定されたアクセスレベルよりも、アクセサ個別のアクセスレベルのほうが厳しくないとエラーとなる。
(「アクセサのレベル」を「プロパティのレベル」よりも緩めることはできない。)
アクセス修飾子の詳細はリンク先を参照。
// プロパティ Sample01 のアクセスレベル : public
// setter のアクセスレベル : private
public string Sample01 { get; private set; }
// プロパティ Sample02 のアクセスレベル : private
// getter のアクセスレベル : protected
// ⇒ レベルを緩めようとしているためエラー
private string Sample02 { protected get; set; }
init アクセサ
初期化時にのみ使用できるアクセサ。C# 9.0で追加された。
詳細はリンク先を参照。