Karakuri.com

Fintechではたらくアプリケーションエンジニアの技術録

TryParseを例外発生の防止に使うのは間違った使い方

C#でTryParseは安全な型変換のために使われますが、単に例外を回避するためだけに使っているケースがあります。今回はTryParseのアンチパターン(悪い使い方)と正しい使い方について書きます。

TryParseの間違った使い方

問題回避の先延ばし

string str = null;
int value;
int result = Calculator(10, int.Parse(str));
    
...
    
private void Calculator(int val1, int val2)
{
   return val1 / val2;
}

当然なのですが、上記のコードは落ちます。この問題を回避するために下記のように書いているコードがありました。

string str = null;
int value;
int.TryParse(str, out value);
int result = Calculator(10, value);
    
...
    
private void Calculator(int val1, int val2)
{
   return val1 / val2;
}

確かに先のコードで落ちていたところでは落ちません。でもその先で落ちます。このコードだったら気づきますが、パースの結果を変数に格納し、後で使う場合は気づきません。これなら前者のコードで落ちたほうがバグに気づくのでマシです。これは実際に本当にあったケースです。

TryParseを使うのをやめる

try
{
   string str = null;
   int result = Calculator(10, int.Parse(str));
}
catch (ArgumentNullException ex)
{
   log.write(ex.Message);
   return;
}
catch (FormatException ex)
{
   log.write(ex.Message);
   return;
} 

呪文のようにTryParseだけ使うくらいならtry catchしたほうがマシです。これならログも残るので、意図しないパースが走ってもデバックできます。ただ、やみくもにtry catchすれば良いわけでもありません。例外の発生は計算コストが高いのでパフォーマンスには悪影響です。例外の発生が予見できるなら、その例外は発生しないようにするべきです。

TryParseの正しい使い方

バリデーションとしてTryParseを使う

string str = null;
int value;

if (int.TryParse(str, out value))
{
   int result = Calculator(10, value);
   ...
}
else
{
   ...
}

TryParseは結果をboolで返してくれるので、それで処理を分けるというのが正しい使い方です。