C#のcatchがちょっと面白い
最近C#をちょっと書いているのだが、まったく未知のところからやっているとつい変なコードを書いてしまう。
先日は、こんなコードを書いた。
using System; // for Exception class Program { private static void Main() { try { throw new Exception("error!"); } catch (Exception) { } } }
見ての通り、catch
句に受け取る型名しか書いていない。なんでこんなことが起きるのかとTwitterでつぶやいたら、こんな感じで教えていただいた。
@xxmagai エラー情報を参照しない場合は、変数の記述は不要ですね。エラー情報を参照せず、後片付けしか行わない時に使います。catchブロックの中でthrow;って書くともう一度例外が投げれるので、片付けして再送出するみたいな場合も書かないです。
— neko (@techno_neko) 2015, 6月 27
実用的には、あるクラスの例外だけ再スローして、ほかの例外は処理する、などに使えるのだろう。
using System; class ExceptionA : Exception { // 関係ないけどコンストラクタいちいち書かないといけないのなんとかならんの? public ExceptionA(string message) : base(message) { } } class Program { private static void Main() { try { throw new ExceptionA("error!"); } catch (ExceptionA) { // こうすると再スローできる throw; } catch (Exception e) { // ExceptionA以外のExceptionクラスの例外は、処理する Console.Write(e); } // こうすると残りぜんぶ取れる catch { } } }
型のゆるい言語を使っていると、catchした後にクラスを見て処理とか考えてしまうが、型の厳しい言語ではこういうやり方があるのだろう。
型の厳しい言語はほとんど使ったことがないので勉強になる。