whenは、例外をフィルタリングするためのキーワードです。catch文の後ろに置き、その時点でスコープにある任意の値を含む真偽値の式を取ることができます。式が真と評価されれば、そのcatch文に対応するブロックが実行され、そうでなければ、次にcatch文があればそれが調べられます。
try
{
// do stuff
}
catch (Exception ex) when (ex.Message != "")
{
// output the message when it is not empty
}
catch (Exception ex)
{
// show stack trace or something.
}
ユーザー定義例外とは、自分のコードで定義するクラスのうち、System.Exceptionから派生したものすべてを指します。クラス継承のルールにすべて従いますが、それに加えて、コンパイラーと言語ランタイムはこのようなクラスを特別に扱い、exceptions演習で説明するように、通常の制御フローを外れてそのインスタンスをスローしたりキャッチしたりできるようにします。
ユーザー定義例外は、メッセージやその他の関連データといった追加情報を運び、それをキャッチするルーチンから利用できるようにするためによく使われます。
_Instruments of Texas_で働いているあなたは、C#で書かれた実験的な電卓の開発を任されています。まずは掛け算から始めて、いくつかの電卓の機能を検証するテストハーネスを作成します。掛け算の2つのオペランドがどちらも負の場合には、特に注意が必要になることがわかるでしょう。
Calculatorクラスはすでに用意されています。変更しないでください。
CalculationExceptionの定義を完成させるCalculationExceptionのコンストラクターの定義を完成させてください。このコンストラクターは、電卓がスローした例外と、その例外がスローされた時点で処理していたオペランドの両方を保存(ラップ)する必要があります。
CalculatorTestHarness.Multiply()メソッドを実装してください。このメソッドは、コンストラクターに渡されたCalculatorインスタンスのCalculator.Multiply()メソッドを呼び出し、xとyの整数値を渡します。Calculator.Multiply()メソッドでオーバーフローが発生すると、OverflowExceptionがスローされます。この例外はCalculatorTestHarness.Multiply()メソッドでキャッチしてCalculationExceptionでラップし、そのとき受け渡されているxとyの値を、その例外のオペランドとして保存してください。新しく作成したCalculationExceptionオブジェクトをスローしてください。Calculator.Multiply()メソッドが成功した場合の戻り値は無視してかまいません。
var cth = new CalculatorTestHarness(new Calculator());
cth.Multiply(Int32.MaxValue, Int32.MaxValue);
// => throws an instance of CalculationException
var cth2 = new CalculatorTestHarness(new Calculator());
cth2.Multiply(3, 2);
// => silently exits
2つの整数を引数に取り、CalculatorTestHarness.Multiply()メソッドを呼び出すCalculatorTestHarness.TestMultiplication()メソッドを実装してください。"Multiply succeeded"が返されます。
var cth = new CalculatorTestHarness(new Calculator());
cth.TestMultiplication(6, 7);
// => "Multiply succeeded"
CalculatorTestHarness.TestMultiplication()メソッドを変更して、2つの整数引数がどちらも負(0より小さい)の場合に"Multiply failed for negative operands. <INNER_EXCEPTION_MESSAGE>"が返されるようにしてください。
<INNER_EXCEPTION_MESSAGE>プレースホルダーは、CalculationExceptionの内部例外のメッセージで置き換えてください。
var cth = new CalculatorTestHarness(new Calculator());
cth.TestMultiplication(-2, -Int32.MaxValue);
// => "Multiply failed for negative operands. " + innerException.Message
CalculatorTestHarness.TestMultiplication()メソッドを変更して、少なくとも一方の整数引数が負でない場合に"Multiply failed for mixed or positive operands. <INNER_EXCEPTION_MESSAGE>"が返されるようにしてください。
<INNER_EXCEPTION_MESSAGE>プレースホルダーは、CalculationExceptionの内部例外のメッセージで置き換えてください。
var cth = new CalculatorTestHarness(new Calculator());
cth.TestMultiplication(Int32.MaxValue, Int32.MaxValue);
// => "Multiply failed for mixed or positive operands. " + innerException.Message