こんにちは、サイオステクノロジー武井です。今回は、C#のプロパティについて説明したいと思います。
メンバー変数へのアクセス
オブジェクト指向では、一般的にメンバー変数へのアクセスは、直接行われません。誰でも自由に書き換えられたら困るからです。なので、getter、setterメソッドを通して、行われるのが一般的です。Javaなんかだと、メジャーですよね。
getter、setterメソッドを使う場合
まずプロパティを使わない場合、つまりgetter、setterメソッドを使う場合は以下のようなコードになります。
class Program
{
static void Main(string[] args)
{
Product hoge = new Product();
hoge.SetName("ほげ");
hoge.SetPrice(1000);
Console.WriteLine("商品名は" + hoge.GetName() + "で、価格は" + hoge.GetPrice() + "円だよ")
;
}
}
class Product
{
private string name;
private int price;
public string GetName() { return this.name; }
public void SetName(string name) { this.name = name; }
public int GetPrice() { return this.price; }
public void SetPrice(int price) {
if (price > 0) throw new ArgumentException();
this.price = price;
}
}
Productというクラスがあり、2つのメンバー変数name(商品名)、price(価格)があります。そのメンバー変数にアクセスするためのメソッドとして、GetName、SetName、GetPrice、SetPriceがあります。商品名にほげ、価格に1000をセットして結果を表示しています。
プロパティを使う場合
プロパティは、クラスその外から見るとメンバー変数のように振る舞い、クラスの内部から見るとメソッドのように振る舞います。プロパティを使う場合は以下のようなコードになります。
class Program
{
static void Main(string[] args)
{
Product hoge = new Product();
// このようにNameやPriceに代入するとsetが呼ばれます。
hoge.Name = "ほげ";
hoge.Price = 1000;
// このようにNameやPriceにアクセスすると、getが呼ばれます。
Console.WriteLine("商品名は" + hoge.Name + "で、価格は" + hoge.Price + "円だよ");
}
}
class Product
{
private string name;
private int price;
// setter、getterの代わりに以下のように定義します。
// クラスの外部から[インスタンス名].Nameとアクセスしたときにgetが呼ばれて、
// [インスタンス名].Name = ...のように何かを代入すると、setが呼ばれます。
public string Name {
get {
return name;
}
set {
name = value;
}
}
public int Price
{
get
{
return price;
}
set
{
if (value > 0) throw new ArgumentException();
price = value;
}
}
}
最初にご紹介した、Productクラスを利用する側からgetter、setterメソッドを使う場合より、記述がスッキリしたような気がしませんか?Productクラスを利用する側から、メンバー変数に何かを代入するときに、わざわざメソッド経由というのは、直感的ではなく、コードもなんかグチャッとします。とは言うもののクラスを作成する側からすれば、直接メンバー変数への代入は避けたいところです。どんな値でも自由に入れられるのはバグの温床にもなります。ProductのPriceみたいに0円未満は例外としたいときもあります。そこでプロパティなのです。
改めて見比べてみますと、setterメソッドを使って変数に代入する場合は、
hoge.SetPrice(1000);
となりますが、プロパティの場合は
hoge.Price = 1000;
となります。プロパティ使ったほうが直感的でスッキリしていますよね。当然、このときsetも呼ばれますので、0円未満は例外となります。
自動プロパティ
C#の自動プロパティを使うと、さらに以下のように記述を省略することが出来ます。
class Program
{
static void Main(string[] args)
{
Product hoge = new Product();
hoge.Name = "ほげ";
hoge.Price = 1000;
Console.WriteLine("商品名は" + hoge.Name + "で、価格は" + hoge.Price + "円だよ");
}
}
class Product
{
private int price;
public string Name { get; set; }
public int Price
{
get
{
return price;
}
set
{
if (value > 0) throw new ArgumentException();
price = value;
}
}
}
以下の記述を削除して、
private string name;
Nameのget、setの部分を以下のように変更しました。
public string Name { get; set; }
より記載がシンプルになりました。
get-onlyプロパティ
getだけのプロパティも定義できます。この場合、Productクラスの利用者はsetは使えません。コンストラクタだけで値を代入して、それ以外の代入方法を潰したいときに便利です。
class Program
{
static void Main(string[] args)
{
Product hoge = new Product("ほげ",1000);
// hoge.Name = "ほげ"; ← この記述はコンパイルエラーになります。
Console.WriteLine("商品名は" + hoge.Name + "で、価格は" + hoge.Price + "円だよ");
}
}
class Product
{
public Product(string name,int price) {
if (price > 0) throw new ArgumentException();
Name = name;
Price = price;
}
public string Name { get; }
public int Price { get; }
}

