English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
ここでは、C#でtry、catch、finallyブロックを使用した例外処理の知識を学びます。
アプリケーション内の例外を処理する必要があります。これにより、プログラムのクラッシュや予期せぬ結果を防ぎ、例外を記録し、他の機能の実行を続けることができます。C#はtry、catch、finallyブロックを使用して例外を処理する内蔵サポートを提供します。
構文:
try { // ここにコードを置くと例外が発生する可能性があります } catch { // ここで例外を処理します } finally { // 最終的なクリーンアップコード }
try ブロック:例外を引き起こす可能性のあるコードは、try{ }ブロックに含める必要があります。実行中に例外が発生すると、制御フローは最初に一致するcatchブロックにジャンプします。
catch ブロック:catchブロックは例外処理ブロックであり、例外の詳細を取得するために使用できます。例外の詳細を取得するために、例外のタイプのパラメータを取得できます。
finally ブロック:finallyは例外が発生したかどうかにかかわらず、常にこのブロックを実行します。通常、finallyブロックはリソースを解放するために使用されます。例えば、tryブロックでオープンしたストリームやファイルオブジェクトを閉じます。
非数字文字を入力した場合、以下の内容が例外を引き起こす可能性があります。
class Program { static void Main(string[] args) { Console.WriteLine("Enter a number: "); var num = int.Parse(Console.ReadLine()); Console.WriteLine($"Squre of {num} is {num"); * num"); } }
上記の例で可能な例外を処理するには、コードをtryブロックで包装し、次のようにcatchブロックで例外を処理します。
class Program { static void Main(string[] args) { try { Console.WriteLine("Enter a number: "); var num = int.parse(Console.ReadLine()); Console.WriteLine($"Squre of {num} is {num"); * num"); } catch { Console.Write("Error occurred."); } finally { Console.Write("Re");-異なる数で another try を行ってください."); } } }
上記の例では、このコードをtryブロックで包装します。tryブロック内で例外が発生した場合、プログラムはそのcatchブロックにジャンプします。catchブロック内では、ユーザーにエラーデータを表示するメッセージを表示し、finallyブロック内では、プログラムの実行が完了した後に表示するメッセージを表示します。
tryブロックはcatchまたはfinallyまたはその両方のブロックに続く必要があります。tryブロックでcatchまたはfinallyブロックを使用しない場合、コンパイル時エラーが発生します。
理想的には、catchブロックには内蔵またはカスタム例外クラスのパラメータを含めて、エラーデータを取得する必要があります。以下では、Exceptionはすべてのタイプの例外をキャッチするtypeパラメータを含んでいます。
class Program { static void Main(string[] args) { try { Console.WriteLine("Enter a number: "); var num = int.parse(Console.ReadLine()); Console.WriteLine($"Squre of {num} is {num"); * num"); } catch(Exception ex) { Console.Write("Error info:"); + ex.Message); } finally { Console.Write("Re");-異なる数で another try を行ってください."); } } }
異なる例外タイプのパラメータを持つ複数の catch ブロックを使用することができます。これは例外フィルタと呼ばれます。異なるタイプの例外を異なる方法で処理したい場合に、例外フィルタは非常に役立ちます。
class Program { static void Main(string[] args) { Console.Write("数を入力して割るために、"); 100: "); try { int num = int.Parse(Console.ReadLine()); int result = 100 / num; Console.WriteLine("100 / {0} = {1} } catch(DivideByZeroException ex) { Console.Write("ゼロで割ることはできません。もう一度試してください."); } catch(InvalidOperationException ex) { Console.Write("無効な操作です。もう一度試してください."); } catch(FormatException ex) { Console.Write("有効な形式ではありません。もう一度試してください."); } catch(Exception ex) { Console.Write("エラーが発生しました!もう一度試してください."); } } }
上記の例では、異なる例外タイプを持つ複数の catch ブロックを指定しました。したがって、ユーザーに適切なメッセージを表示し、ユーザーが同じエラーを再び作成しないようにすることができます。
無パラメータの catch ブロックと Exception パラメータを持つ catch ブロックを同じ try..catch 文で使用することは許可されていません。なぜなら、それらは同じ操作を実行するからです。
try { //例外を引き起こす可能性のあるコード } catch //catch と catch(Exception 異常)を同時に持つことはできません { Console.WriteLine("例外が発生しました"); } catch(Exception ex) //catch と catch(異常異常)を同時に持つことはできません { Console.WriteLine("例外が発生しました"); }
また、パラメータのない catch ブロック catch {} または一般的な catch ブロック catch (Exception ex){} は最後のブロックでなければなりません。catch {} または catch (Exception ex) ブロックの後に他の catch ブロックがある場合、コンパイラはエラーを出力します。
例:無効なcatchキャッチ
try { //例外を引き起こす可能性のあるコード } catch { // このキャッチブロックは最後のブロックでなければなりません } catch(NullReferenceException nullEx) { Console.WriteLine(nullEx.Message); } catch(InvalidCastException inEx) { Console.WriteLine(inEx.Message); }
finallyブロックはオプションのブロックで、tryまたはcatchブロックの後に配置されるべきです。例外が発生するかどうかにかかわらず、finallyブロックは常に実行されます。finallyブロックは通常、非統合オブジェクトの処理などのクリーンアップコードに使用されます。
例:finallyブロック
static void Main(string[] args) { FileInfo file = null; try { Console.Write("書き込むファイル名を入力してください: "); string fileName = Console.ReadLine(); file = new FileInfo(fileName); file.AppendText("Hello World!") } catch(Exception ex) { Console.WriteLine("エラーが発生しました: {0}", ex.Message); } finally { // ここでファイルオブジェクトをクリーンアップします; file = null; } }
finallyブロックを使用することはできません。 複数のブロックがあります。また、finallyブロックにはreturn、continue、またはbreakキーワードを含むことはできません。finallyブロックからコントロールを離れることは許可されていません。
C#ではネストのtryが許可されています。-catchブロックを使用する場合、-catchブロックが発生した場合、catchのtryブロックの後で最初に一致するブロックで例外をキャッチします。
static void Main(string[] args) { var divider = 0; try { try { var result = 100/divider; } catch { Console.WriteLine("内部 catch"); } } catch { Console.WriteLine("外部 catch"); } }
内部catch
上記の例では、catchはすべての例外を処理する最初のブロックであるため、内部のブロックを実行します。
内部のcatchブロックに対応する例外の種類が無い場合、コントロールは外部のcatchブロックに流れます。適切な例外フィルタを見つけるまで続きます。以下の例を参照してください。
static void Main(string[] args) { var divider = 0; try { try { var result = 100/divider; } catch(NullReferenceException ex) { Console.WriteLine("内部 catch"); } } catch { Console.WriteLine("外部 catch"); } }
外部 catch
上記の例では、DivideByZeroException が発生します。内部の catch ブロックは NullReferenceTypeException を処理するため、外部の catch ブロックで処理されます。