クラスのメンバ変数は、クラスの外部から直接値を操作できないようにアクセスレベルに private などに指定することが多々あります。
これは、設計者の意図しない値が渡されたときにバグの原因になりますし危険な行為だからです。
主に、これを回避するためにメンバ変数のアクセスレベルを指定し、メソッドの内部でデータの検証を行う方法が取られます。
class Sample
{
private int no;
public void SetMethod( int i )
{
// 値の検証を行い、正しい値であれば i の値をセットします。
this.no = i;
}
public int GetMethod()
{
return this.no;
}
}
class MyClass
{
Sample x = new Sample();
x.SetMethod(100); // 意図した値か検証します。
Console.WriteLine(x.GetMethod()); // 値を取り出します。
}
このように、メンバ変数の値の取得(GetMethod())、変更(SetMethod())を行うためのメソッドのことを アクセサ (または アクセッサ)メソッドと呼びます。
しかし、これでは検証を行いたい数だけ get/set メソッドが必要になるし、何より変数のように扱えたら便利ですよね。
C#では、フィールドとメソッドの両方の側面を兼ね備えた プロパティ と呼ばれる技術が用意されています。
プロパティは static や オーバーライド をすることもできます。
- データ型 プロパティ名
{
get // get アクセサ
{
}
set // set アクセサ
{
}
}
まず get アクセサですが、これは必ず return ステートメントまたは throw ステートメントで終了する必要があります。
これは、プロパティの要求があった時に呼び出されます。
set アクセサは、戻り値が void のメソッドと似ていて、プロパティに値を代入するときに呼び出されます。
代入された値は value という名前の暗黙のパラメータに格納されます。
この2つのアクセサは、どちらか一方を省略することができます。
ちなみに、set アクセサを省略した場合は、get アクセサしかもたないので、読み取り専用のプロパティとして扱います。
逆に、get アクセサを省略した場合は、書き込み専用のプロパティとして扱います。
//サンプル38
using System;
namespace ConsoleApplication
{
abstract class Shape // 抽象クラス
{
public abstract int Age
{
get;
set;
}
}
class PropSample : Shape
{
private int age;
public override int Age
{
get
{
return this.age;
}
set
{ // 受け取った値は value に格納されます。
if (value >= 0) this.age = value;
}
}
}
class Sample38
{
public static void Main()
{
PropSample obj = new PropSample();
obj.Age = 23; // メソッドの時とは違い、値は "=" で渡します。
Console.WriteLine("私は{0}歳です。",obj.Age); // メンバ変数にアクセスするときと同じ要領です。
}
}
}
.NET 2.0
プロパティの set/get アクセサに、それぞれ異なるアクセスレベルを設定することができます。
class Sample
{
private int no;
public int No
{
get // get アクセッサ
{
return this.no;
}
protected set // set アクセッサ
{
this.no = value;
}
}
}