C#のプロパティ

こんにちは、サイオステクノロジー武井です。今回は、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; }
}
ご覧いただきありがとうございます! この投稿はお役に立ちましたか?

役に立った 役に立たなかった

1人がこの投稿は役に立ったと言っています。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です