クラスにプロパティを定義する | Visual C# プログラミング

SPECIAL


クラスにプロパティを定義する

プロパティというのは、インスタンス毎に特徴を設定する変数(属性)のようなものです。

クラスのインスタンス変数ごとに特徴を持たせ、変数を読み書きするように利用できます。読み書きされた際に実行するコードも記載できるので、プロパティの値が変化したときに、それに付随するさまざまな処理を実行することもできます。

このとき、プロパティを読み書きする機能のことを「アクセサ」と言い、そのうち読み取りの方を「ゲッター」と呼び、書き込みの方を「セッター」と呼びます。

読み書き可能なプロパティを定義する(自動プロパティ)

C# でプロパティを定義するには、次のように記述します。

public class MyClass

{

public string Description

{

get;

set;

}

}

まず、どの範囲からそのプロパティへアクセスできるかを "public" や "protected"、"private" で指定しています。

続いてプロパティのデータ型、そしてプロパティ名を定義しています。その次の { } の中では、そのプロパティを読み書きする際の処理を記載します。get が読み取る場合の処理で、set が書き込む場合の処理を表します。

C# ではこのように、"get;" と "set;" とだけ記載して、その処理の内容を書かないことで、このプロパティが扱える型のデータを単純に保持したり取得したりするできるだけのプロパティになります。

 

余談ですが、このような "get;" や "set;" だけで実装されたプロパティのことを C# では「自動プロパティ」(Auto-Implemented properties) と呼ぶようです。

読み取り専用のプロパティを定義する(自動プロパティ)

値を読み取るだけで、書き込めないプロパティを定義するには、次のようにします。

public class MyClass

{

public string Name

{

get;

private set;

}

}

これを自動プロパティで定義する場合、値を読み取る "get;" は通常どおり記載します。値を書き込むための "set;" には、先頭に "private" や "protected" を記載して、外側から自由に書き込めないようにします。

読み取るだけなら "get;" でも良さそうに思えますが、このように "set;" も定義しないと、クラス内部でこのプロパティに値を設定することができません。

プロパティの読み書き時に任意の処理を実行する

C# では、アクセサを実装することで、プロパティの読み書き時に任意の処理を実行できます。

たとえば、クラスに "Int32" 型の "_price" というメンバー変数を定義して、それを "Price" プロパティを通して読み書きする場合は次のようにします。

public class MyClass

{

// 変数は外部から直接操作されないように private で定義します。

private Int32 _price;

 

// プロパティは外部からアクセスできるようにします。

public Int32 Price

{

// ゲッターでは、メンバー変数の値を返しています。

get

{

return _price;

}

 

// セッターには、代入された値が value 変数にわたってくるので、それをメンバー変数に設定しています。

set

{

_price = value;

}

}

}

メンバー変数を外から読み書きできないようにするのは、オブジェクト指向の「カプセル化」という考え方に依るものです。たとえばプロパティがもう少し複雑で、メンバー変数はその処理を補助するものだったようなとき、外部からメンバー変数だけが不用意に変更されてしまうのを防げます。

アクセサを自分で実装するとき、ゲッターでは最終的に "return" 構文を使って値を返すようにします。セッターでは、プロパティに設定された値が "value" 変数として渡されるので、これを使って適切な処理を行います。

 

なお、読み取り専用のプロパティを定義する場合、自動プロパティでは "protected set;" のような、内部的に値を設定するためのセッターが必要でしたが、自分で実装する場合にはゲッターだけを定義すれば大丈夫です。

たとえば、プロパティ "Price" に設定されている値を 1.1 倍にしたものを取得できる "PriceIncludingTax" プロパティを読み取り専用で実装する場合、次のように定義できます。

public Int32 PriceIncludingTax

{

get

{

return Convert.ToInt32(Math.Floor(this.Price * 1.1));

}

}


[ もどる ]