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

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

C#エンジニア 案件・求人一覧はこちら

C#のプロパティとは?

C#のプロパティとは、クラスのメンバ変数を手軽に使えるようにするための便利な機能です。ただしプロパティについて学ぶ前に、まずオブジェクト指向の概念の一つ「カプセル化」について理解しておく必要があります。以下のプログラムを見てください。

 

お役立ち情報を受け取りたい方はこちらからメルマガ登録をどうぞ!

 

カプセル化の具体例

クラスHumanのメンバ変数に値を代入し、その後で取り出しています。上のようなプログラムはとても手軽で簡単です。個人の趣味でプログラミングをする際にはこのようなスタイルでも全く問題は無いでしょう。

しかし、業務で大規模なシステムのプログラミングをする場合、このような作りにはしません。以下のようにします。

getterとsetterはカプセル化には必須

Humanクラスのメンバ変数をprivateにして直接アクセスせず、getメソッドとsetメソッドでアクセスします。このメソッドはgetterとsetterと呼ばれます。なぜこのようにする必要があるのでしょうか。

大勢で1つのシステムの開発を行う場合、自分の担当していないクラスの中身まで知る必要はなく、ブラックボックスとして扱えるようにしなければなりません。クラスのインターフェイスの仕様を知るだけで使えるようにするべきです。この設計手法がカプセル化です。

具体的には上の例のようにクラスのメンバ変数はprivateにして、アクセスするメソッドをpublicとして公開する作り方を、カプセル化と言います。

getterとsetterのメリット

getterとsetterを使うことでカプセル化ができるだけでなく、範囲チェックやログ出力も可能になります。例えば上の例のsetAgeメソッド内で、以下のようなことができます。

クラスのメンバ変数をpublicにして直接アクセスしていると、このような前処理はできません。

getterとsetterのデメリット

しかしgetterとsetterは良い事ばかりではありません。クラスのメンバ変数が多くなるとgetterとsetterの数がとても多くなり、非常に見づらいソースコードになります。C++やJavaなどの開発環境ではgetterとsetterを自動生成してくれる機能もありますが、見づらいことには変わりありません。

その問題を解決してくれるのが、C#のプロパティなのです。

プロパティでgetterとsetterを簡略化

C#のプロパティを使えばgetterとsetterを以下のように簡略化できます。

プロパティならメンバ変数に簡単にアクセスできる

上の例では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#のプロパティにはクラスのメンバ変数は必ずしも必須ではありません。以下のようにメンバ変数と無関係なプロパティを作ることもできます。

これを実行すると以下のようになります。普通のメソッドでやれば良いようにも感じますが、役に立つ場合もあるかもしれません。

山田
value is 太郎

自動プロパティで記述を更に簡略化できる

C#には「自動プロパティ」という機能があり、これを使うとプロパティの記述を更に簡略化できます。以下のようにします。

メンバ変数を記述せずに、プロパティへの値の代入と取得ができてしまいます。なお、プロパティ内部で使用されている変数については隠蔽されていて、見ることはできません。

また自動プロパティは単純な代入・取得だけしかできないので、例えば値の範囲チェックなどを行いたい場合、自動プロパティは使えません。

読み取り専用のプロパティ

C#では読み取り専用のプロパティを作ることも可能です。以下のようにします。

クラスのインスタンス生成時のコンストラクタのみで代入可能になるので、途中で値を変更されたくない場合に便利です。

式形式のプロパティ

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#のプロパティで配列変数を使いたい場合はどうすればいいのでしょうか。以下のようにすれば可能です。

これを実行すると以下のようになります。

太郎
花子
幸雄

おわりに

C#のプロパティについて理解できましたでしょうか。プロパティはC++やJavaといった他のオブジェクト指向言語にはない優れた機能なので、是非活用してみてください。

C#エンジニア 案件・求人一覧はこちら
 

お役立ち情報を受け取りたい方はこちらからメルマガ登録をどうぞ!

 

インフラエンジニア専門の転職サイト「FEnetインフラ」

FEnetインフラはサービス開始から10年以上『エンジニアの生涯価値の向上』をミッションに掲げ、多くのエンジニアの就業を支援してきました。

転職をお考えの方は気軽にご登録・ご相談ください。

合わせて読みたい

文字列の検索とは|C#の文字列検索に使うメソッド6種などいくつか紹介します... hbspt.cta.load(20723875, 'd567c97b-58b2-483a-83fe-aec2e001739a', {"useNewLoader":"true","region":"na1"}); 文字列の検索とは 文字列の検索とは、検索エンジンのように指定したキーワードを...
C#のswitch文を解説!if文との違いやさまざまな使い方を紹介... hbspt.cta.load(20723875, 'd567c97b-58b2-483a-83fe-aec2e001739a', {"useNewLoader":"true","region":"na1"}); C#のswitch文とは? まずはswitch文を使ってみよう C#にはs...
【組み込み】C#からPythonを呼び出す方法を紹介... hbspt.cta.load(20723875, '4d5ed975-c4a9-41ec-8e28-71f1d092cb5c', {"useNewLoader":"true","region":"na1"}); 組み込みとは? 一般に、特定の機能を家電製品や機械などに埋め込んで利用すること...
C#のラムダ式は難しくない!実例でわかるC#のラムダ式でできること9つを紹介... hbspt.cta.load(20723875, 'd567c97b-58b2-483a-83fe-aec2e001739a', {"useNewLoader":"true","region":"na1"}); C#のラムダ式とは? C#のラムダ式(lambda expressions)...
C#のLINQにチャレンジしてみよう! hbspt.cta.load(20723875, 'd567c97b-58b2-483a-83fe-aec2e001739a', {"useNewLoader":"true","region":"na1"}); C#のLINQとは? C#のLINQとはLanguage-Integrated ...