C#のプロパティを使いこなそう!さまざまな実装方法を紹介
 
          C#のプロパティとは?

C#のプロパティとは、クラスのメンバ変数を手軽に使えるようにするための便利な機能です。ただしプロパティについて学ぶ前に、まずオブジェクト指向の概念の一つ「カプセル化」について理解しておく必要があります。以下のプログラムを見てください。
| 
                          1
                         
                          2
                         
                          3
                         
                          4
                         
                          5
                         
                          6
                         
                          7
                         
                          8
                         
                          9
                         
                          10
                         
                          11
                         | 
                          class Human
                         
                          {
                         
                           public string name;
                         
                           public int age;
                         
                          }
                         
                          Human hu = new Human();
                         
                          hu.name = "太郎";
                         
                          hu.age = 20;
                         
                          Console.WriteLine(hu.name + " " + hu.age);
                         | 
カプセル化の具体例
クラスHumanのメンバ変数に値を代入し、その後で取り出しています。上のようなプログラムはとても手軽で簡単です。個人の趣味でプログラミングをする際にはこのようなスタイルでも全く問題は無いでしょう。
しかし、業務で大規模なシステムのプログラミングをする場合、このような作りにはしません。以下のようにします。
| 
                          1
                         
                          2
                         
                          3
                         
                          4
                         
                          5
                         
                          6
                         
                          7
                         
                          8
                         
                          9
                         
                          10
                         
                          11
                         
                          12
                         
                          13
                         
                          14
                         
                          15
                         
                          16
                         
                          17
                         
                          18
                         
                          19
                         
                          20
                         
                          21
                         
                          22
                         
                          23
                         
                          24
                         
                          25
                         
                          26
                         
                          27
                         
                          28
                         | 
                          class Human
                         
                          {
                         
                           private string m_name;
                         
                           private int m_age;
                         
                           public string getName()
                         
                           {
                         
                            return m_name;
                         
                           }
                         
                           public int getAge()
                         
                           {
                         
                            return m_age;
                         
                           }
                         
                           public void setName(string name)
                         
                           {
                         
                            m_name = name;
                         
                           }
                         
                           public void setAge(int age)
                         
                           {
                         
                            m_age = age;
                         
                           }
                         
                          }
                         
                          Human hu = new Human();
                         
                          hu.setName("太郎");
                         
                          hu.setAge(20);
                         
                          Console.WriteLine(hu.getName() + " " + hu.getAge());
                         | 
getterとsetterはカプセル化には必須
Humanクラスのメンバ変数をprivateにして直接アクセスせず、getメソッドとsetメソッドでアクセスします。このメソッドはgetterとsetterと呼ばれます。なぜこのようにする必要があるのでしょうか。
大勢で1つのシステムの開発を行う場合、自分の担当していないクラスの中身まで知る必要はなく、ブラックボックスとして扱えるようにしなければなりません。クラスのインターフェイスの仕様を知るだけで使えるようにするべきです。この設計手法がカプセル化です。
具体的には上の例のようにクラスのメンバ変数はprivateにして、アクセスするメソッドをpublicとして公開する作り方を、カプセル化と言います。
getterとsetterのメリット
getterとsetterを使うことでカプセル化ができるだけでなく、範囲チェックやログ出力も可能になります。例えば上の例のsetAgeメソッド内で、以下のようなことができます。
| 
                          1
                         
                          2
                         
                          3
                         
                          4
                         
                          5
                         
                          6
                         
                          7
                         
                          8
                         
                          9
                         | 
                           public void setAge(int age)
                         
                           {
                         
                            if (age < 0)
                         
                           {
                         
                            ※「ageの値が範囲外」といったエラーログ出力処理をする
                         
                            return;
                         
                           }
                         
                           m_age = age;
                         
                           }
                         | 
クラスのメンバ変数をpublicにして直接アクセスしていると、このような前処理はできません。
getterとsetterのデメリット
しかしgetterとsetterは良い事ばかりではありません。クラスのメンバ変数が多くなるとgetterとsetterの数がとても多くなり、非常に見づらいソースコードになります。C++やJavaなどの開発環境ではgetterとsetterを自動生成してくれる機能もありますが、見づらいことには変わりありません。
その問題を解決してくれるのが、C#のプロパティなのです。
プロパティでgetterとsetterを簡略化
C#のプロパティを使えばgetterとsetterを以下のように簡略化できます。
| 
                          1
                         
                          2
                         
                          3
                         
                          4
                         
                          5
                         
                          6
                         
                          7
                         
                          8
                         
                          9
                         
                          10
                         
                          11
                         
                          12
                         
                          13
                         
                          14
                         
                          15
                         
                          16
                         
                          17
                         
                          18
                         
                          19
                         
                          20
                         
                          21
                         
                          22
                         | 
                          class Human
                         
                          {
                         
                           private string m_name;
                         
                           private int m_age;
                         
                           public string Name // m_nameのプロパティ
                         
                           {
                         
                            get { return m_name; }
                         
                            set { m_name = value; }
                         
                           }
                         
                           public int Age // m_ageのプロパティ
                         
                           {
                         
                            get { return m_age; }
                         
                            set { if (value >= 0) m_age = value; }
                         
                           }
                         
                          }
                         
                          Human hu = new Human();
                         
                          hu.Name = "太郎";
                         
                          hu.Age = 20;
                         
                          Console.WriteLine(hu.Name + " " + hu.Age);
                         | 
プロパティならメンバ変数に簡単にアクセスできる
上の例ではNameがm_nameのプロパティ、Ageがm_ageのプロパティとなります。プロパティの中ではsetとgetでアクセス処理を記述しています。Ageのsetにあるように、範囲チェックなどの処理も加えることができます。
プロパティのメンバ変数への値の代入と取得は「クラス変数.プロパティ」で行えます。メンバ変数に直接アクセスする記述と似ていますが、ちゃんとプロパティ内に記述したgetとsetの処理は呼び出されています。
プロパティのアクセス制御
プロパティのgetとsetはそのままでpublicな状態で自由にアクセスできますが、宣言でアクセシビリティを設定すれば個別にアクセスを制御できます。
protected set { m_age = value; }
このようにすれば同じクラスと派生したクラスでのみプロパティに値を代入できるようになります。
private set { m_age = value; }
こうすれば、同じクラス内だけしかm_ageに値を入れることはできません。クラスの外からは読み取りだけにしたい場合に使えますね。
プロパティにはメンバ変数は必須ではない
実はC#のプロパティにはクラスのメンバ変数は必ずしも必須ではありません。以下のようにメンバ変数と無関係なプロパティを作ることもできます。
| 
                          1
                         
                          2
                         
                          3
                         
                          4
                         
                          5
                         
                          6
                         
                          7
                         
                          8
                         
                          9
                         
                          10
                         
                          11
                         
                          12
                         
                          13
                         | 
                          class Human
                         
                          {
                         
                           public string Yamada
                         
                           {
                         
                            get { return "山田"; }
                         
                            set { Console.WriteLine("value is " + value); }
                         
                           }
                         
                          }
                         
                          Human hu = new Human();
                         
                          Console.WriteLine(hu.Yamada);
                         
                          hu.Yamada = "太郎";
                         | 
これを実行すると以下のようになります。普通のメソッドでやれば良いようにも感じますが、役に立つ場合もあるかもしれません。
山田
            value is 太郎
自動プロパティで記述を更に簡略化できる
C#には「自動プロパティ」という機能があり、これを使うとプロパティの記述を更に簡略化できます。以下のようにします。
| 
                          1
                         
                          2
                         
                          3
                         
                          4
                         
                          5
                         
                          6
                         
                          7
                         
                          8
                         
                          9
                         
                          10
                         
                          11
                         
                          12
                         
                          13
                         | 
                          class Human
                         
                          {
                         
                           // メンバ変数は不要
                         
                           public string Name
                         
                           {
                         
                            get; set; // これだけでOK
                         
                           }
                         
                           public int Age
                         
                           {
                         
                            get; set; // これだけでOK
                         
                           }
                         
                          }
                         | 
メンバ変数を記述せずに、プロパティへの値の代入と取得ができてしまいます。なお、プロパティ内部で使用されている変数については隠蔽されていて、見ることはできません。
また自動プロパティは単純な代入・取得だけしかできないので、例えば値の範囲チェックなどを行いたい場合、自動プロパティは使えません。
読み取り専用のプロパティ
C#では読み取り専用のプロパティを作ることも可能です。以下のようにします。
| 
                          1
                         
                          2
                         
                          3
                         
                          4
                         
                          5
                         
                          6
                         
                          7
                         
                          8
                         
                          9
                         
                          10
                         
                          11
                         
                          12
                         
                          13
                         
                          14
                         
                          15
                         
                          16
                         
                          17
                         
                          18
                         
                          19
                         
                          20
                         
                          21
                         | 
                          class Human
                         
                          {
                         
                           public string Name
                         
                           {
                         
                            get; // getのみを記述
                         
                           }
                         
                           public int Age
                         
                           {
                         
                            get; // getのみを記述
                         
                           }
                         
                           //コンストラクタ
                         
                           public Human(string name, int age)
                         
                           {
                         
                            Name = name; // プロパティに代入
                         
                            Age = age; // プロパティに代入
                         
                           }
                         
                          }
                         
                          Human hu = new Human("太郎", 20);
                         
                          Console.WriteLine(hu.Name + " " + hu.Age);
                         | 
クラスのインスタンス生成時のコンストラクタのみで代入可能になるので、途中で値を変更されたくない場合に便利です。
式形式のプロパティ
C#は読み取り専用のプロパティを使って、式形式のプロパティを作ることができます。例としては、上のHumanクラスに以下の1行のプロパティを追加します。
public string NameAndAge => Name + ” ” + Age;
これを以下のように使用することができます。
Human hu = new Human(“太郎”, 20);
            Console.WriteLine(hu.NameAndAge);
結果は以下になります。
太郎 20
自動プロパティの初期化
C#の自動プロパティには初期値を持たせることができます。以下のようにすれば初期化できます。
public string Name { get; set; } = “花子”;
            public int Age { get; set; } = 30;
普通の自動プロパティでもgetだけの読み取り専用のプロパティでも、同様に初期化出来ます。
プロパティの配列
C#のプロパティで配列変数を使いたい場合はどうすればいいのでしょうか。以下のようにすれば可能です。
| 
                          1
                         
                          2
                         
                          3
                         
                          4
                         
                          5
                         
                          6
                         
                          7
                         
                          8
                         
                          9
                         
                          10
                         
                          11
                         
                          12
                         
                          13
                         | 
                          class Human
                         
                          {
                         
                           public string[] NameAry { get; set; }
                         
                          }
                         
                          Human hu = new Human();
                         
                          string[] names = new string[] { "太郎", "花子", "幸雄" };
                         
                          hu.NameAry = names;
                         
                          for (int i = 0; i < hu.NameAry.Length; i++)
                         
                          {
                         
                           Console.WriteLine(hu.NameAry[i]);
                         
                          }
                         | 
これを実行すると以下のようになります。
太郎
            花子
            幸雄
おわりに
C#のプロパティについて理解できましたでしょうか。プロパティはC++やJavaといった他のオブジェクト指向言語にはない優れた機能なので、是非活用してみてください。
FEnetを運営しているネプラス株式会社はサービス開始から10年以上
          『エンジニアの生涯価値の向上』をミッションに掲げ、
          多くのインフラエンジニア・ネットワークエンジニアの就業を支援してきました。
          
ネプラス株式会社はこんな会社です
秋葉原オフィスにはネプラス株式会社をはじめグループのIT企業が集結!
          数多くのエンジニアが集まります。

- 
              インフラ業界に特化 ネットワーク・サーバー・データベース等、ITインフラ業界に特化。Cisco Systemsプレミアパートナーをはじめ各種ベンダーのパートナー企業です。 業界を知り尽くしているからこそ大手の取引先企業、経験豊富なエンジニアに選ばれています。 
- 
              正社員なのにフリーランスのような働き方 正社員の方でも希望を聞いたうえでプロジェクトをアサインさせていただいており、フリーランスのような働き方が可能。帰社日もありません。 プロジェクト終了後もすぐに次の案件をご紹介させていただきますのでご安心ください。 
- 
              大手直取引の高額案件 案件のほとんどが大手SIerやエンドユーザーからの直取引のためエンジニアの皆様へに高く還元できています。 Ciscoをはじめ、Juniper、Azure、Linux、AWS等インフラに特化した常時300件以上の案件があります。 
- 
              スキルアップ支援 不要なコストを削減し、その分エンジニアの方へのスキルアップ支援(ネットワーク機器貸出、合格時の受験費用支給など)や給与で還元しています。 受験費用例)CCNP,CCIE:6-20万円、JNCIS:3-4万円、AWS:1-3万円など ※業務に関連する一定の資格のみ。各種条件がありますので詳しくは担当者へにお尋ねください。 
- 
              現給与を保証します!※ 前職の給与保証しており、昨年度は100%の方が給与アップを実現。収入面の不安がある方でも安心して入社していただけます。 ※適用にはインフラエンジニアの業務経験1年以上、等一定の条件がございます。 
- 
              インセンティブ制度 ネットワーク機器の販売・レンタル事業等、売上に貢献いただいた方にはインセンティブをお支払いしています。 取引先企業とエンジニア側、双方にメリットがあり大変好評をいただいています。 
- 
              社会保険・福利厚生 社員の方は、社会保険を完備。健康保険は業界内で最も評価の高い「関東ITソフトウェア健康保険組合」です。 さらに様々なサービスをお得に利用できるベネフィットステーションにも加入いただきます。 
- 
              東証プライム上場企業グループ ネプラスは東証プライム上場「株式会社夢真ビーネックスグループ」のグループ企業です。 安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。 
ネプラス株式会社に興味を持った方へ
ネプラス株式会社では、インフラエンジニアを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
              オンライン面接も随時受付中。ぜひお気軽にご応募ください。


C#新着案件New Job
- 
              
              【高額年収】/競馬場向け音声案内ツール運用保守/神奈川県横浜市/【WEB面談可/インフラサーバ経験者/20~40代の方活躍中】/在宅勤務年収600万~720万円神奈川県横浜市(桜木町駅)
- 
              
              【高額年収】/ECサイト運用保守/Windows/東京都23区東部/【WEB面談可】/在宅勤務/20代~40代の方活躍中年収600万~720万円東京都23区東部(-駅)
- 
              
              【高額年収】/共通基盤や製品に関わる運用保守/C#/東京都中野区/【WEB面談可】/在宅勤務/20代~40代の方活躍中年収600万~720万円東京都中野区(中野駅)
- 
              
              ECサイト構築/Windows/東京都23区東部/【WEB面談可】/在宅勤務/20代~40代の方活躍中年収540万~720万円東京都23区東部(-駅)
- 
              
              VR・AIサービス運用保守/C#/東京都品川区/【WEB面談可】/在宅勤務/20代~40代の方活躍中年収600万~720万円東京都品川区(五反田駅)
- 
              
              Web受付ツール及びサーバ運用保守/東京都千代田区/【WEB面談可/インフラサーバ経験者/20~40代の方活躍中】/在宅勤務年収480万~660万円東京都千代田区(飯田橋駅)









