連載

C#入門

第12 インデクサとプロパティ

(株)ピーデー
川俣 晶
2001/09/27


プロパティを使う

 プロパティは、Visual Basicなどに存在していた機能なので、Visual Basicのベテランであれば、すぐに理解することができるだろう。

 プロパティとは、クラスのメンバ変数であるかのようにアクセス可能でありながら、処理の内容を自分で記述できる機能である。インデクサが配列であるかのようにアクセスできる機能とすれば、プロパティはメンバ変数であるかのように記述できる手段を提供する機能である。実際のプロパティを記述したサンプルソースを以下に示す。

 1: using System;
 2:
 3: namespace ConsoleApplication43
 4: {
 5:   class Class2
 6:   {
 7:     private int number;
 8:     public string Order
 9:     {
10:       get {
11:         switch( number )
12:         {
13:           case 1:
14:             return "one";
15:           case 2:
16:             return "two";
17:           case 3:
18:             return "three";
19:           default:
20:             return "unknown";
21:         }
22:       }
23:       set {
24:         switch( value )
25:         {
26:           case "one":
27:             number = 1;
28:             break;
29:           case "two":
30:             number = 2;
31:             break;
32:           case "three":
33:             number = 3;
34:             break;
35:           default:
36:             number = -1;
37:             break;
38:         }
39:       }
40:     }
41:   }
42:   class Class1
43:   {
44:     static void Main(string[] args)
45:     {
46:       Class2 t = new Class2();
47:       t.Order = "one";
48:       Console.WriteLine( t.Order );
49:     }
50:   }
51: }
プロパティを使用したサンプル・プログラム7
プロパティはメンバ変数であるかのようにメソッドを記述できる。

 このプログラムを実行すると以下のようになる。

サンプル・プログラム7の実行結果
Mainメソッドでは“one”という文字列を保存しているように見えるが、内部では“one”を数値の“1”に置き換えて保存している

 まず、プロパティの宣言は8行目で行われている。8行目の書式はインデクサの宣言と似ているが、名前はthisではなく、具体的に自分で付けた名前(ここではOrder)となる。インデクサは角括弧で表されるので、名前で区別することは意味がないが、プロパティは変数のふりをするので、変数同様名前を付けて区別する意味がある。

 処理内容の記述方法は、インデクサと同じなので説明を繰り返さない。その代わり、このサンプルソースでは、記憶する内容と、読み書きする内容を差し替えるという処理を示している。このサンプルソースでは、文字列を読み書きするプロパティOrderを定義しているが、実際に保存される値は7行目で宣言されている整数型変数のnumberに納められる。47行目に記述されているように"one"という文字列を代入すると、23〜38行目のset処理が実行される。その中で、26行目の「case "one":」により、27行目が実行され、変数numberには1が書き込まれる。そして、48行目のt.Orderは10〜22行目のget処理を呼び出し、13行目の「case 1:」により、14行目が処理され、"one"という文字列が返される。その結果、画面にはoneという文字列が表示される。

 あたかも、oneという文字列を、Class2のインスタンスが保持しているかのように見えるが、実際にはoneを数値の1に置き換えて保存しているのである。このように、内部で保持するデータ形式と、外部に見せるデータ形式が一致しないときに、そのギャップを埋めるのがプロパティの使い方の1つである。

 このようなケースは、ソフトのチューンナップなどを行っているとしばしば発生する。データの内部表現を変えれば高速化できると分かったとき、プロパティを使えば、内部表現を変更しながら、外部に見せるインターフェースは変更しない、ということが実現できるのである。

プロパティと+=演算子

 +=演算子は、a += bとしたときに、変数aにbを加え、変数aに戻すという機能を実現する。このとき、変数ではなくプロパティを使うとどうなるだろうか。つまり、クラスClass2にプロパティNumberがあるとき、これに+=演算子を使ったら何が起こるだろうか、と言うことである。実際に試した結果を以下に示す。

 1: using System;
 2:
 3: namespace ConsoleApplication44
 4: {
 5:   class Class2
 6:   {
 7:     private int number;
 8:     public int Number
 9:     {
10:       get
11:       {
12:         Console.WriteLine("property get called");
13:         return number;
14:       }
15:       set
16:       {
17:         Console.WriteLine("property set called");
18:         number = value;
19:       }
20:     }
21:   }
22:   class Class1
23:   {
24:     static void Main(string[] args)
25:     {
26:       Class2 t = new Class2();
27:       t.Number = 1;
28:       t.Number += 2;
29:       Console.WriteLine( t.Number );
30:     }
31:   }
32: }
プロパティに「+=演算子」を使用したサンプル・プログラム8
プロパティを記述しているsetとgetはどのように呼び出されるのだろうか?

 このプログラムを実行すると以下のようになる。

サンプル・プログラム8の実行結果
+=演算子ではプロパティの読み出しと書き込みの両方が発生している。

 このサンプルソースのクラスClass2のNumberプロパティは、ただ単に整数を変数numberに保存するという機能を提供する。ただし、getとsetの処理が呼び出されたことが分かるように、12行目と17行目に、メッセージ出力のコードを入れてある。

 処理の内容を順番に見ていこう。まず、26行目でClass2のインスタンスが作成される。そして、27行目で、値1がプロパティに代入され、12行目により"property set called"が出力される。次に、28行目が処理されるが、ここではNumberプロパティの読み出しと、書き込みの両方が発生している。その結果、get処理が呼ばれ"property get called"が表示され、それに引き続き、set処理が呼ばれ"property set called"が表示されている。つまり、getして2を足してsetしていると言うことである。その結果、変数numberは、もともと1であったところに2が足されて3になる。そして画面表示最終行の手前の"property get called"は、29行目のプロパティNumberの参照によって表示されたものである。当然、3という足し算の結果が最後の行に表示される。

 このように、+=演算子が有効に機能するデータ型のプロパティであれば、プロパティに+=演算子を使うことができる。


 INDEX
  第12回 インデクサとプロパティ
    1.インデクサとは何か
    2.インデクサを自作する
  3.プロパティを使う
    4.好ましくない使い方
 
「C#入門」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間