連載

C#入門

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

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


好ましくない使い方

 インデクサとプロパティは、うまく使えばプログラムを簡潔に記述することができて便利なのだが、一歩使い方を間違うと、トラブルの種にもなる。

 まず、以下のサンプルソースを見て頂きたい。21〜24行目を見て、結果を容易に推測出来るだろうか?

 1: using System;
 2:
 3: namespace ConsoleApplication45
 4: {
 5:   class Sum
 6:   {
 7:     private int sum = 0;
 8:     public int Add
 9:     {
10:       set { sum += value; }
11:     }
12:     public int Result
13:     {
14:       get { return sum; }
15:     }
16:   }
17:   class Class1
18:   {
19:     static void Main(string[] args)
20:     {
21:       Sum sum = new Sum();
22:       sum.Add = 1;
23:       sum.Add = 2;
24:       Console.WriteLine( sum.Result );
25:     }
26:   }
27: }
プロパティの好ましくない使い方を示すサンプル・プログラム9
21〜24行目を見て、結果を容易に推測出来るだろうか?

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

サンプル・プログラム9の実行結果
プロパティが変数に見せかけた処理であるとすれば、この結果は直感に反する。

 つまり、結果は3になる。22行目の1と23行目の2が足されて3である。しかし、プロパティとは変数に見せかけた処理であるとすれば、この結果は直感に反する。つまり、23行目でプロパティに2を代入しているのだから、22行目で代入した1は消えてなくなって、2がオブジェクトの中に入ると考えるのが自然である。決して、23行目のコードから足し算が行われるとは読みとれない。確かに、Addというキーワードが足し算を連想させる言葉かもしれないが、誰もがそれだけで足し算を行うと連想できるわけではない。しかも足し算だと推理したところで、何と何を足すのかは、22〜23行目からは読みとれない。これらの問題から、プロパティをこのように使うのは好ましいことではないと言える。

 これは以下のように書く方がベターと言える。

 1: using System;
 2:
 3: namespace ConsoleApplication46
 4: {
 5:   class Sum
 6:   {
 7:     private int sum = 0;
 8:     public void Add( int number )
 9:     {
10:       sum += number;
11:     }
12:     public int Value
13:     {
14:       set { sum = value; }
15:       get { return sum; }
16:     }
17:   }
18:   class Class1
19:   {
20:     static void Main(string[] args)
21:     {
22:       Sum sum1 = new Sum();
23:       sum1.Add( 1 );
24:       sum1.Add( 2 );
25:       Console.WriteLine( sum1.Value );
26:
27:       Sum sum2 = new Sum();
28:       sum2.Value += 1;
29:       sum2.Value += 2;
30:       Console.WriteLine( sum2.Value );
31:     }
32:   }
33: }
プロパティのベターな使い方を示すサンプル・プログラム10
Addをプロパティではなくメソッドに変更している。また、保持している値sumをプロパティValueでアクセス可能にしている。

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

サンプル・プログラム10の実行結果
メソッドの記述も、プロパティの記述も処理内容が直感的に理解できる。

 ここではAddをプロパティではなくメソッドに変更している。メソッド呼び出しであれば、誰も変数のように振る舞うという予断は持たないので、メソッドの処理内容を確認するまでは、結果を推理しないだろう。一方、Valueの方は、単なる内部変数の読み書きを行うだけなので、プロパティとして実装しても混乱することはない。むしろ、メソッドにするよりも、プロパティの方が分かりやすくて好ましい。読み書き両用のプロパティValueがあれば、28〜29行目のような記述も可能になる。これは、誰が見ても処理内容が直感的に理解でき、非常に好ましい。

 このような問題はプロパティだけでなくインデクサにも起こる。以下がその例である。このプログラムがどんな数値を出力するか、ソースコードから容易に読みとれるだろうか?

 1: using System;
 2:
 3: namespace ConsoleApplication47
 4: {
 5:   class Class2
 6:   {
 7:     private int a = 0;
 8:     public int this[int index]
 9:     {
10:       get
11:       {
12:         return a + index;
13:       }
14:       set
15:       {
16:         a = index + value;
17:       }
18:     }
19:   }
20:   class Class1
21:   {
22:     static void Main(string[] args)
23:     {
24:       Class2 t = new Class2();
25:       t[1] = 2;
26:       Console.WriteLine( t[3] );
27:     }
28:   }
29: }
インデクサの好ましくない使い方を示すサンプル・プログラム11
どんな数値を出力するかプログラムから容易に読みとれるだろうか?

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

サンプル・プログラム11の実行結果
インデクサの添え字を足し算に使用しており、定義を全て読まないと挙動が推理できない。

 このサンプルソースの中のインデクサは、まるで配列変数のように振る舞わない。このようなインデクサは、ソースコードを読む者に混乱を与えるだけなので、記述すべきではない。定義を全て読まないと挙動が推理できないとすれば、インデクサの価値はない。素直にメソッドを使うべきだろう。

まとめ

 理論的には、プロパティとインデクサは、存在しなかったとしてもプログラムを記述できる機能である。実際、Javaにはプロパティもインデクサも存在しないが、実用ソフトがいくつも記述されている。しかし、すべてメソッドに頼ったコーディングは、ソースコードが長くなる傾向にある。

system.get_somethig().get_hoge(index)

 のような長い式は、直感的に把握しがたい。これを、

system.somethig[index]

 と書けるようになるだけで、把握しやすさが向上するとはいえないだろうか?

 さて、次回はプロパティやインデクサと並んで非常にC#らしい機能といえるイベントついて解説したいと思っている。

 それでは次回もLet's See Sharp!End of Article


 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 記事ランキング

本日 月間