C#のtry~catchの使い方の紹介!|try~catchで例外処理を正しく使いこなそう

- システム
エンジニア - try~catchの例外処理は具体的にどのような処理ができるのですか。
- プロジェクト
マネージャー - try~catch文は例外処理のほか、さまざまな便利な使い方ができます。詳しくご紹介いたしましょう。
C#のtry~catchとは?
C#では何かの処理を行った時に問題が発生すると、Exceptionという例外が発生します。
try~catch文はそういった例外を処理するのに役立つ機能です。またそれ以外にも便利な使い方ができるので、是非マスターしましょう。
まずは簡単なサンプルを見ていきましょう。以下はtry~catchの使用例です。
1
2
3
4
5
6
7
8
9
|
string s = null;
try
{
Console.WriteLine("文字の長さは" + s.Length);
} catch (Exception e)
{
Console.WriteLine(e.ToString());
}
|
catchで例外をキャッチできる
上のC#サンプルでは、try節の中で文字列sの長さを表示しようとしています。しかしsはnullのため例外のExceptionが発生します。それをcatchで文字通りキャッチできるのです。そしてcatch節で例外の内容を表示します。
このサンプルを実行すると以下のような表示が出ます。
1
2
|
System.NullReferenceException: Object reference not set to an instance of an object.
at TestApp.Program.Main() in C:\Users\〇〇〇\source\repos\TestApp\TestApp\Program.cs:line 14
|
Exceptionのサブクラスもキャッチできる
上のC#サンプルでは参照がnullだった時に発生するNullReferenceExceptionが発生します。しかしcatchで指定しているのはExceptionクラスです。実はcatchは指定したクラスのサブクラスも受けることができます。NullReferenceExceptionがExceptionのサブクラスなのでキャッチできるのです。
このようにExceptionのサブクラスを一括でcatchするのではなく、例外の種類に応じてtry~catchすることもできます。以下のC#サンプルをご覧ください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
int i = 0;
try
{
int a = 3 / i;
} catch (NullReferenceException e)
{
Console.WriteLine("参照がnullです。");
} catch (DivideByZeroException e)
{
Console.WriteLine("0で除算しています。");
} catch (Exception e)
{
Console.WriteLine("上の2つ以外の例外です。");
}
|
複数の種類の例外を個別にキャッチできる
上のC#サンプルを実行すると、0で割り算をしているため例外が発生し、
0で除算しています。
と表示されます。上の方のcatchが優先されるので、ExceptionよりDivideByZeroExceptionが優先されます。
例外はキャッチするだけでなく投げることもできます。以下のサンプルをご覧ください。
1
2
3
4
5
6
7
8
|
try
{
throw new Exception("1つ目の例外");
}
catch (Exception e)
{
throw new Exception("2つ目の例外");
}
|
自分で例外を投げることもできる
上のC#サンプルを実行すると、まずtry節の中でthrowにより1つ目の例外を投げます。すぐにキャッチされて、catch節の中で2つ目の例外を投げます。このように自らExceptionを発生させることもできるのです。
catchにはwhen句で条件を付けることができます。以下のように行います。
1
2
3
4
5
6
7
8
|
try
{
throw new Exception("No.1");
}
catch (Exception e) when(e.Message.Equals("No.1"))
{
Console.WriteLine("No.1をキャッチしました。");
}
|
実行すると、以下の通りに表示されます。Messageの文字列が指定の通りだった時のみ、catchの処理が行なわれます。
1
|
No.1をキャッチしました。
|
ラムダ式でもthrowできる
C#にはラムダ式という文法がありますが、C# 7からそこでも例外を投げることができるようになりました。
1
2
3
4
5
|
public static string GetGoodStr() => "グッドです!";
public static void Main()
{
Console.WriteLine(GetGoodStr());
}
|
これを実行すると「グッドです!」と表示されますが、GetGoodStrを以下のようにすることができます。
1
|
public static string GetGoodStr() => throw new NotImplementedException();
|
この場合は実行すると未実装の意味を示すNotImplementedExceptionが発生します。作っている途中のラムダ式に使用するとよいでしょう。
null合体演算子でもthrowできる
C#にはnull合体演算子の??という機能があります。以下のサンプルをご覧ください。
1
2
3
|
object o = null;
String s = o as String ?? "null";
Console.WriteLine(s);
|
oがnullの場合、??の右の文字列を入れてくれます。これにthrowを使用して、以下のようにnullだった場合に例外を投げることができます。
1
|
String s = o as String ?? throw new Exception("nullです!");
|
三項演算子でもthrowできる
C#には三項演算子(条件演算子)があります。以下の場合、
1
2
3
4
5
6
7
|
string s = null;
s = s != null ? "メッセージは" + s : "nullでした。";
Console.WriteLine(s);
sがnullでなかったら左辺が代入され、nullだったら右辺が代入されます。この右辺を、
s = s != null ? "メッセージは" + s : throw new Exception("nullです!");
|
のようにして例外を投げるようにすることが可能です。
finallyの使い方
C#にはtry~catchと一緒に使うと便利なfinallyという構文があります。以下のように使われるのが一般的です。なおこれを実行する場合、ソースの先頭に「using System.IO;」を追加してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
StreamReader reader = null;
try
{
reader = new StreamReader(@"C:\test\file.txt");
Console.WriteLine(reader.ReadToEnd());
}
catch (IOException e)
{
Console.WriteLine("ファイルを読み込めませんでした。");
}
finally
{
if (reader != null) reader.Close();
}
|
finallyは後始末を確実に行ってくれる
上のC#サンプルは、ファイルを読み込んで中身を表示します。ファイルが無かった場合はIOExceptionが発生して、エラーメッセージを表示します。そしてfinally節でファイルのCloseを行っています。
finallyに書かれた処理は、何があろうと必ず実行されます。例外が発生しても、必ず実行されるのです。だからこのようなファイルのCloseなど忘れてはならない後始末処理にとても便利なのです。
finallyの代わりにusingを使えるケースもある
ただしC#では、上のようなケースはfinallyではなくusingを使う方がおすすめです。上のサンプルでusingを使うと以下のようになります。
1
2
3
4
5
6
7
8
9
10
11
|
try
{
using (StreamReader reader = new StreamReader(@"C:\test\file.txt"))
{
Console.WriteLine(reader.ReadToEnd());
}
}
catch (IOException e)
{
Console.WriteLine("ファイルを読み込めませんでした。");
}
|
usingによる終了処理にはIDisposableの実装が必要
上のサンプルではusingで記述したStreamReaderは{}を抜けた後に確実にCloseされます。それが行われる条件は、対象のクラスがIDisposableを実装していることです。StreamReaderの親クラスのTextReaderはIDisposableを実装しているので、Closeしてくれます。
usingで記述した処理の終了処理が必ず実行されるわけではないことに注意してください。IDisposableを実装してないのであれば、finallyを使いましょう。
- システム
エンジニア - なるほど。try~catchは是非とも使いこなしたい機能ですね。
- プロジェクト
マネージャー - そうですね。try~catchを使いこなせるように、ご紹介したコードをご自身で書いてみてください。
C#のtry~catchで例外処理を使いこなそう
C#のtry~catchについて解説しましたがご理解頂けましたでしょうか。
処理中に問題が起きたときにif文などで対応せずに例外を投げてcatch内で処理するようにしたほうが、正常処理と異常処理を分離できるので良いコードになります。
是非try~catchを活用しましょう。
FEnet.NETナビ・.NETコラムは株式会社オープンアップシステムが運営しています。
株式会社オープンアップシステムはこんな会社です
秋葉原オフィスには株式会社オープンアップシステムをはじめグループのIT企業が集結!
数多くのエンジニアが集まります。

-
スマホアプリから業務系システムまで
スマホアプリから業務系システムまで開発案件多数。システムエンジニア・プログラマーとしての多彩なキャリアパスがあります。
-
充実した研修制度
毎年、IT技術のトレンドや社員の要望に合わせて、カリキュラムを刷新し展開しています。社内講師の丁寧なサポートを受けながら、自分のペースで学ぶことができます。
-
資格取得を応援
スキルアップしたい社員を応援するために資格取得一時金制度を設けています。受験料(実費)と合わせて資格レベルに合わせた最大10万円の一時金も支給しています。
-
東証プライム上場企業グループ
オープンアップシステムは東証プライム上場「株式会社夢真ビーネックスグループ」のグループ企業です。
安定した経営基盤とグループ間のスムーズな連携でコロナ禍でも安定した雇用を実現させています。
株式会社オープンアップシステムに興味を持った方へ
株式会社オープンアップシステムでは、開発系エンジニア・プログラマを募集しています。
年収をアップしたい!スキルアップしたい!大手の上流案件にチャレンジしたい!
まずは話だけでも聞いてみたい場合もOK。お気軽にご登録ください。


C#新着案件New Job
-
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(新宿駅) -
システム開発/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(新宿駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円神奈川県横浜市(桜木町駅) -
デバック、テスト項目の作成/神奈川県横浜市/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円神奈川県横浜市(桜木町駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代前半の方活躍中/経験1年以上の方活躍中】/在宅勤務
月給29万~34万円東京都新宿区(西新宿駅) -
基幹システム開発導入/東京都新宿区/【WEB面談可/C#経験者/20代後半~40代の方活躍中/経験年数不問】/在宅勤務
月給41万~50万円東京都新宿区(西新宿駅)