【C#】プロパティを活用しよう!使う理由と実装方法を解説

「 set get 」って書いてある文を見かけるけど、なんのこと?

プロパティって何?

インタフェースにプロパティは書けるの?

C#を勉強していると、メンバ変数へクラス外部から直接アクセスするのはあまり好ましくなく、メソッドを使ったりした方が良いという事が分かってくるかと思います。その際に活用できるのがプロパティです。

こんにちは、元エンジニアでC#ライターの遠藤です。

今回の記事はこんな方へ向けて書きました。

  • set/getの記述について知りたい
  • プロパティについて知りたい
  • インタフェースなどにもset/getを書きたい

この記事を読んでいただければ、プロパティの基礎的な使い方がわかります。

ぜひ最後までお付き合いください。

目次

C#のset, getとは

以下のようなset, getですが、C#でお見かけしたことはありませんか?

using System;

public class PropertyCls {
    public int PropertyInt{ set; get;} //ここでset, getが書かれている
}

class Program {
    static void Main() {
        PropertyCls p = new PropertyCls();
        p.PropertyInt = 32; //変数に代入しているように見える
        Console.WriteLine(p.PropertyInt);
    }
}

実行結果:

32


set; get;
とだけ書かれているメソッド(上の例ではPropertyInt)、こちらはプロパティと呼ばれるものです。

以降の章では、そのプロパティについて解説していきます!

プロパティとは

まずはじめに、プロパティとはメンバ変数の値の取得や変更を行う為のメソッド(アクセサー)の事です。

冒頭でも述べましたが、メンバ変数へのクラス外部から直接アクセスできるようにするのは、あまり好ましくありません。

その理由としては、オブジェクトの状態が不正な値に書き換えられエラーとなってしまったり、そのメンバ変数が絡んだ修正が入った時にオブジェクトの値を利用する側のクラスの修正量が増えてしまったりするリスクがあるためです。

そのため、メンバ変数は基本的にそのクラス内だけで利用し外部クラスから直接アクセスできない状態にして、メンバ変数とのやりとりはメソッドを活用するようにする事が望ましいとされています。

とはいえ、メンバ変数の数だけメソッドを用意したら、コード行数も多くなってしまって手間ですよね。それを簡略化させて速記できるようにしたのが、プロパティです。

プロパティの書き方・使い方

ここで、プロパティの具体例をご確認ください。

using System;

public class PropertyCls { //プロパティを記述するクラス
    
    // メンバ変数は外部から隠蔽(privateに)しておき、直接アクセスできないようにする
    private int propertyInt;

    // 変数の取得・変更用のプロパティ
    public int PropertyInt
    {
        set{ propertyInt = value; } //値の代入
        get { return propertyInt; } //外部に値を返す
    }
}

class Program { //プロパティを利用するクラス
    static void Main() {
        PropertyCls p = new PropertyCls(); //インスタンスを生成
        p.PropertyInt = 32; //値を代入(setを呼ぶ)
        Console.WriteLine(p.PropertyInt); //値を取得(getを呼ぶ)
    }
}

実行結果:

32

上記のように、プロパティを使うと値の取得・変更を set{},get{} だけでひとかたまりに記述する事ができます。

また、利用者側のクラスでは、変数に直接アクセスしているかのように「インスタンス.プロパティ名」だけで値のやりとりができるようになるのがプロパティの利点です。

書き方としてまずプロパティを記述するクラスでは「アクセスレベル型 プロパティ名{} 」で宣言し、その中に set{}, get{} を記述します。

set{}の中には主に「メンバ変数 = value」というように記述します。valueは利用者側のクラスで代入された値が格納される予約語です。

get{}の中には「return メンバ変数」というように、戻り値を指定する形になります。

その後利用者側のクラスでインスタンスを生成し、値の取得時は「インスタンス名.プロパティ名」で get{} を呼び出し、「インスタンス名.プロパティ名 = 値」で set{} を呼び出します。

このように実装する事で、プロパティを記述するクラスではメソッドとして扱う事ができ、かつ利用者側のクラスではメンバ変数のように扱う事ができるようになります。

省略形

C# 3.0以降では特別な処理を加えない場合、以下のように省略する事も可能です。

アクセスレベル 型 プロパティ名{ set; get;}

先ほどのサンプルをこの省略形にすると、

using System;

public class PropertyCls { //プロパティを記述するクラス
    public int PropertyInt{ set; get;}
}

class Program { //プロパティを利用するクラス
    static void Main() {
        PropertyCls p = new PropertyCls(); //インスタンスを生成
        p.PropertyInt = 32; //値を代入(setを呼ぶ)
        Console.WriteLine(p.PropertyInt); //値を取得(getを呼ぶ)
    }
}

このようになります。実行結果は同じです。

この実装の仕方だと1点差分があり、メンバ変数の宣言が行われていないのでクラス内でも set{},get{} でしかアクセスできない状態になります。

このとき変数に相当するフィールドはあるのですが、コンパイラによって生成されるバックフィールドと呼ばれ、プログラマがアクセスできない領域になります。

ちなみに、同一クラス内でも set{},get{} を使ったほうが良い場合が多いです。したがって、変数を宣言する必要がないので、このような機能があります。

set{}, get{}のアクセスレベルについて

C# 2.0以降では、set{}, get{} のアクセスレベルを変更する事も可能です。

using System;

public class PropertyCls {
    public int PropertyInt{ protected set; get;} //setにprotectedを指定
}

class Program {
    static void Main() {
        PropertyCls p = new PropertyCls();
        p.PropertyInt = 32; //値を代入(protectedなのでエラーになる)
    }
}

set{} を protectedにしたので、利用者側ではアクセスできなくなります。

実行結果:

set アクセサーにアクセスできないため、プロパティまたはインデクサー 'PropertyCls.PropertyInt' はこのコンテキストでは使用できません。

get{} はデフォルトのpublicなので、アクセスが可能です。

get-onlyについて

C# 6.0以降では、get-onlyという記述のやり方が可能になります。これは、set{} を記述しない書き方です。

get-onlyにするとコンストラクタでのみ値を代入できるようになり、以降は変更不可となります。

using System;

public class PropertyCls {
    public int PropertyInt{ get;} //setにprotectedを指定

    public PropertyCls(int propertyint)
    {
        PropertyInt = propertyint;
    }
}

class Program {
    static void Main() {
        PropertyCls p = new PropertyCls(32);
        Console.WriteLine(p.PropertyInt);
    }
}

 

実行結果:

32

インタフェースとプロパティ

インタフェースでメソッドを宣言するのと同様に、プロパティを宣言することが可能です。

例:

using System;

public interface IPropertyInterface {
    int PropertyInt{ get; set; }
}

public class InterfaceUser : IPropertyInterface
{
    protected int propertyInt;
    public int PropertyInt
    {
        get{ return propertyInt; }
        set{ propertyInt = value; }
    }
}

public class Program : InterfaceUser
{
    
    static void Main() {
        InterfaceUser p = new InterfaceUser();
        Console.WriteLine(p.PropertyInt);
        p.PropertyInt = 128;
        Console.WriteLine(p.PropertyInt);
    }
}

 

実行結果:

0
128

まとめ

今回の記事では、以下について解説致しました。

  • プロパティとは
  • プロパティの書き方・使い方
  • インタフェースにプロパティを書く方法

プロパティはプログラミングする規模が大きくなるにつれ、目にする機会も増えてくるかと思います。

ここで使い方を覚えて、スマートなコーディングをしてください!

この記事を書いた人

【プロフィール】
DX認定取得事業者に選定されている株式会社SAMURAIのマーケティング・コミュニケーション部が運営。「質の高いIT教育を、すべての人に」をミッションに、IT・プログラミングを学び始めた初学者の方に向け記事を執筆。
累計指導者数4万5,000名以上のプログラミングスクール「侍エンジニア」、累計登録者数1万8,000人以上のオンライン学習サービス「侍テラコヤ」で扱う教材開発のノウハウ、2013年の創業から運営で得た知見に基づき、記事の執筆だけでなく編集・監修も担当しています。
【専門分野】
IT/Web開発/AI・ロボット開発/インフラ開発/ゲーム開発/AI/Webデザイン

目次