「 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
まとめ
今回の記事では、以下について解説致しました。
- プロパティとは
- プロパティの書き方・使い方
- インタフェースにプロパティを書く方法
プロパティはプログラミングする規模が大きくなるにつれ、目にする機会も増えてくるかと思います。
ここで使い方を覚えて、スマートなコーディングをしてください!