初心者のためのC#プログラミング本格入門101 - 詳細を意識しないで済む状態にしよう
今度もテストから始めます。ある程度機能が整ってきたので、今度は耐久テストを行います。耐久テストというのは、ある程度無茶な使い方をしても正常に処理されるのかをチェックするテストです。オブジェクトを使う人は通常、オブジェクト内部を意識しませんから、想定外の使い方をされても大丈夫なようにプログラミングしておかねばなりません。それは、他人のためだけにする行為ではありません。
詳細を知っておかないと使えないオブジェクトは、使い勝手が非常に悪いです。たとえ自分がプログラミングしたオブジェクトであっても、永遠に詳細まで覚えておくことなど不可能に近いです。従って、将来の自分のためにも詳細を知らないでもよい作り方をしておくのが賢明だといえます。
具体例を挙げて解説します。まずは、テストプログラムを改良し、ちょっと無茶な使い方を試してみましょう。
class SimpleListTest : Test
{
//他のプログラムは省略しています。
public void AddElementCheck()
{
base.Execute();
for ( int i = 0 ; i < 10000 ; ++i ) {
this.target.Add( i );
int result = this.target[ i ];
if ( result != i ) {
string message = "予期せぬ値が返されました。" +
"予想値:" + i +
" 返された値" + result;
base.Error( message );
}
}
}
}
きっと、1万個も追加するとは思っていないでしょう。しかし、そういった盲点にバグは生まれます。テストを実行すると案の定、プログラムが止まってしまいます。プログラムが止まったら、デバッガが表示する情報を見てみましょう。配列の範囲外にアクセスしていることが問題だと分かります。配列の要素数が10個になっているのが目に見える問題です。だったら、2万個ほど確保しておけばいいと、考える人がいるかもしれません。しかし、問題は数だけではありません。どれだけ確保しても、それ以上の要素を追加する人が居るかもしれません。もし前提があると、「このオブジェクトは2万個までしか追加できないぞ」などと注意せねばなりません。非常に面倒です。それに加えて、常に無数の要素を追加したいわけではありません。初めから何万個も確保しようとせず、少量だけ用意しておき、後で何個でも追加できるようにしておくほうが便利ではないでしょうか?
何個でも追加できるように簡単に変更できます。
ただしこのプログラム、大きな問題があります。テストを改良して自分で発見してください。続く...partial class SimpleList { //他のプログラムは省略しています。 public void Add( int value ) { ++this.insertIndex; if ( this.insertIndex == this.data.Length ) { this.data = new int[ this.data.Length * 2 ]; } this.data[ this.insertIndex ] = value; } }