初心者のためのC#プログラミング本格入門86 - 執拗に攻めよう
前回サンプルプログラムのバグを潰しました。しかし本当にバグはもうないのでしょうか?テストデータを追加して検証してみましょう。
public void CalculateMultiExpression()
{
TestData[] tests = new TestData[]
{
//基本チェック
new TestData( "( + 1 2 ) + 3", ( 1 + 2 ) + 3 ),
new TestData( "( + 1 2 ) * 3", ( 1 + 2) * 3 ),
new TestData( "( + 1 2 ) - 3", ( 1 + 2 ) - 3 ),
new TestData( "( + 1 2 ) / 3", ( 1 + 2 ) / 3 ),
//演算の順番チェック
new TestData( "( + 3 4 ) + 3", ( 3 + 4 ) + 3 ),
new TestData( "( + 3 4 ) * 3", ( 3 + 4 ) * 3 ),
new TestData( "( + 3 4 ) - 3", ( 3 + 4 ) - 3 ),
new TestData( "( * 3 4 ) / 3", ( 3 * 4 ) / 3 ),
//3個の式をチェック
new TestData( "( + 10 1 ) ( + 2 1 ) + 3",
( 10 + 1 ) + ( 2 + 1 ) + 3 ),
new TestData( "( + 1 2 ) ( * 2 ) * 2",
( 1 + 2 ) * 2 * 2 ),
new TestData( "( + 10 5 ) ( - 3 ) - 5",
( 10 + 5 ) - 3 - 5 ),
new TestData( "( * 10 2 ) ( / 2 ) / 2",
( 10 * 2 ) / 2 / 2 ),
//4個の式をチェック
new TestData( "( + 10 1 ) ( + 2 1 ) ( + 3 ) + 4",
( 10 + 1 ) + ( 2 + 1 ) + 3 + 4 ),
};
foreach ( TestData test in tests )
{
CalculateMultiExpression(
test.Expression, test.RightValue );
}
}
デバッグ実行(F5)して下さい。3個以上の複合式ではエラーが発生しています。複数のエラーが表示されていますが、3個の式での加算処理(最初)と4個の式(最後)に注目してみましょう。よく見ればエラーの原因が分かると思います。この2つの結果をよく見ると、加算処理が2回しか行われていない事が分かります。ということは、MultiAnalyzerオブジェクトのCalculationメソッドが怪しいと言えます。Calculationメソッドのプログラムをよく見るか、ブレークポイントを設定して、ステップイン(F11)とステップオーバー(F10)の機能を使い、プログラムの実行中の値をよく観察すれば分かります。ステップイン(F11)とステップオーバー(F10)は、デバッグ機能の一種です。ブレークポイントを使って止まった時に使用します。この2つの機能を使うと、プログラムを一行ずつ実行する事が可能となります。この機会に使ってみて下さい。エラーの原因が分かったら読み進めて下さい。
分かりましたか?答えは「double backValue = analyzers[ i - 1 ].Calculation();」の部分です。このプログラムだと、前式の計算結果が反映されていません。それで2回分しか計算されていないのです。つまり、作業用につくった変数tempsで処理をするのが正解です。念のために、修正したプログラムを掲載します。
//計算式の計算結果を返す
public double Calculation()
{
//初期値を設定
double result = 0.0f;
//複数の式を計算
System.Collections.Generic.List<Analyzer> temps =
new System.Collections.Generic.List<Analyzer>();
temps.Add ( new Analyzer( analyzers[ 0 ] ) );
if ( analyzers.Count > 1 )
{
for ( int i = 1; i < this.analyzers.Count; ++i )
{
Analyzer temp = new Analyzer( analyzers[ i ] );
double backValue = temps[ i - 1 ].Calculation();
temp.AddValues( backValue );
temps.Add( temp );
}
}
//最終的な計算結果を返す
result = temps[ temps.Count - 1 ].Calculation();
return result;
}
デバッグ実行(F5)して下さい。今度はエラーが表示されません。今回の解説で分かったと思いますが、テストはしつこいぐらい念入りに行いましょう。バグは油断を栄養にして増殖します。これでもまだテスト量が全然足りません。実務ではもっと詳細に行います。初心者用の記事と言う事もあり現在はテストが不十分です。テストを十分に行うには、覚えるべき文法があります。適切な時に紹介するので楽しみにして下さい。