C#のプロパティを使いこなそう!さまざまな実装方法を紹介
- システム
エンジニア - C#のプロパティはどのような実装方法があるのでしょうか?
- プロジェクト
マネージャー - カプセル化や簡略化、初期化することが可能です。
C#のプロパティとは?
C#のプロパティとは、クラスのメンバ変数を手軽に使えるようにするための便利な機能です。ただしプロパティについて学ぶ前に、まずオブジェクト指向の概念の一つ「カプセル化」について理解しておく必要があります。以下のプログラムを見てください。class Human{ public string name; public int age;} Human hu = new Human();hu.name = “太郎”;hu.age = 20;Console.WriteLine(hu.name + ” ” + hu.age);
カプセル化の具体例
クラスHumanのメンバ変数に値を代入し、その後で取り出しています。上のようなプログラムはとても手軽で簡単です。個人の趣味でプログラミングをする際にはこのようなスタイルでも全く問題は無いでしょう。しかし、業務で大規模なシステムのプログラミングをする場合、このような作りにはしません。以下のようにします。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メソッド内で、以下のようなことができます。 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を以下のように簡略化できます。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#のプロパティにはクラスのメンバ変数は必ずしも必須ではありません。以下のようにメンバ変数と無関係なプロパティを作ることもできます。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#には「自動プロパティ」という機能があり、これを使うとプロパティの記述を更に簡略化できます。以下のようにします。class Human{ // メンバ変数は不要 public string Name { get; set; // これだけでOK } public int Age { get; set; // これだけでOK }}メンバ変数を記述せずに、プロパティへの値の代入と取得ができてしまいます。なお、プロパティ内部で使用されている変数については隠蔽されていて、見ることはできません。また自動プロパティは単純な代入・取得だけしかできないので、例えば値の範囲チェックなどを行いたい場合は自動プロパティは使えません。
読み取り専用のプロパティ
C#では読み取り専用のプロパティを作ることも可能です。以下のようにします。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#のプロパティで配列変数を使いたい場合はどうすればいいのでしょうか。以下のようにすれば可能です。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#のプロパティについて理解できましたでしょうか。プロパティはC++やJavaといった他のオブジェクト指向言語にはない優れた機能なので、是非活用してみてください。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。
-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社オープンアップグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。
C#新着案件New Job
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅) -
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)