2011-12-07 6 views
0

ここでの主な例は、単語文書のコピーです。プログラム内に次のコード行があります。プログラムのエラーをチェックするために例外を使用することはできますか?

try 
{ 
    File.Copy(docTemplatePath, docOutputPath, true); 
} 
catch (IOException e) 
{ 
    MessageBox.Show(e.ToString()); 
} 

エラーチェックでビルドしようとしています。私は、保存しようとする前に、出力されたWord文書が別の場所で開かれていないことを確認します。そうしないと例外がスローされます。

私が見ているのは、コードのデフォルト機能が期待通りに機能しないというエラーを警告するために例外がスローされるということです。この意味では、問題を識別するためにそれを読んで(この場合、文書は現在他の場所でロックされている/開いている)、例外をキャッチして、ユーザーに実際にその文書を知らせるMessageBox別の場所で開いているファイルに書き込みます。

これでいいですか?私はこれを見て、例外が何をするように設計されているように見えるのか、それをどうやって人々が例外を使って考えているように見えるのか、多くの場所を見てきました。自分自身をチェックすることを好むだろう。

全体的なコンセンサスは何ですか?

ありがとうございます。

答えて

2

例外を使用して、例外的な発生を処理する必要があります。

です。ユーザが入力したファイル名が存在しない可能性があるので、コードはロードする前にFile.Exists()をチェックする必要があります(例外に依存しないなど)。

このファイルはすでに使用中でロックされています。は例外的な状況です。それはおそらくちょうど良いです。それは私見

+0

例外的な状況が発生したかどうかは、判断の問題ですか? –

+1

潜在的な発生が「例外的」であると考えるかどうかは、判断の問題です。たとえば、ユーザーは、分母に0を入力して、予測可能で例外的ではありません。インターネット接続が突然失敗する:例外。 –

+0

私は、多くの感謝を見る。 :) –

1

IMOでは、管理された予期しないエラーに例外を使用する必要があります。

認証エラー(不正なパスワードなど)に対して例外をスローするのは悪い考えですが、データベース接続エラーの管理にはこれを使用するとよいでしょう。

したがって、私はいくつかの言葉で、予期しない問題を管理するために例外を使用し、ビジネス上の問題は管理しません。例外を伴うすべてのビジネス問題を実行するというアイデアは、オブジェクト指向の「オーバー」アプローチであり、それを使用するべきではありません。

あなたの例は、例外を使用する良い方法のIMOです。 世界的には、機能性や特定のタスクを「大きな」試み/キャッチするだけです。

0

私の知る限りの例外は

、開発者の外にある開発者が問題の知識を持っていない可能性がありますハードウェア障害または切断されたネットワークまたはそれに類似したもの、のように制御し、物事を処理するために設計されていますより良い表現 「行っていない」され、プログラムの流れを制御するための例外を使用しDivideByZeroException

0

をチェックするよりも、int r = val/divider;dividerの値をチェックします。アプリケーション全体をクラッシュさせたくない例外的な状況を処理するためにのみ使用してください。

しかし、時には例外を使用する必要があるとも言われています。私は、.NET Frameworkのint.TryParseメソッドやその他のTryParseメソッドはExceptionsを使用し、動作しない場合はキャッチしてからfalseを返すと考えています。

Wordファイルがすでに開いているかどうかを知る方法が他にない場合は、私の意見では例外を使用してこれを行うことができます。良いことは、他のものが間違っている可能性があるため、特定の例外をキャッチすることです。問題は、IOExceptionに別のソースがある可能性がある(つまり、宛先フォルダにアクセスできないなど)。これは、あなたの例だけでなく、すべての(複雑な)例外駆動型フローについても当てはまります。上記のTryParseの例はかなりシンプルなので、問題はそれほどありません。

結論:あなたができる唯一の方法でない限り、しないでください。そして、別の方法でそれを分離しようとします。こうすれば、より良いソリューションが見つかると、いつでも実装を変更できます。また、最も具体的な例外をキャッチして、例外がいくつかのソースを持つことができることに留意してください。

0

ルーチンが正常に戻ることで契約を満たすことができる場合は、そうする必要があります。ルーチンが契約違反なしで正常に戻ることができない場合は、例外をスローする必要があります。ルーチンの契約が指定されている場合、ルーチンが例外をスローするかどうかを判断するにあたって、判断の余地はあまりありません。それは上記の単純なルールに基づいて戻ったり投げたりするべきです。

定型文に入れられる場所の判断は、ルーチンの契約が何であるべきかを決定することです。有用なパターンは、ルーチンの "試し"バージョンと "実行"バージョンの両方を提供することです。 「試し」バージョンが合理的に予期される問題のために要求されたアクションを実行できない場合は、何らかのタイプのエラー値を返すことによってそのことを示します。何らかの理由で、「Do」バージョンが要求されたアクションを実行できない場合、例外をスローします。

単純な例として、「Integer.TryParse」と「Integer.Parse」と考えてください。有効な数値であってもなくてもよい文字列を持つ場合、Integer.TryParseを呼び出すことができます。 Integer.TryParseは、返されたフラグを使用して、解析が成功したかどうかを示します。解析が成功したかどうかにかかわらず、完全に幸せに戻ります。呼び出し側は、戻り値を使用する前にTryParseが成功したことを確認する責任があります。対照的に、Integer.Parseは、数値が正常に解析された場合にのみ返します。数値が有効でない場合、Integer.Parseは例外をスローします。したがって、呼び出しコードは、成功したかどうかをチェックせずにInteger.Parseによって返された値を使用することができます。 Integer.Parseが成功しなかった場合、それは返されませんでした。本当に例外的なケースでInteger.TryParseが例外をスローする可能性があることに注意してください(たとえば、安全でないコードが渡されたStringリファレンスポイントを他のタイプのオブジェクトに渡した場合など)。唯一保証されるのは、合理的に予想されるケースに投げ込まれないことです(例えば、 "123"のような文字列の代わりに "XYZ"のような文字列が渡されます)。

Try/Doパターンをわずかに強化すると、何か問題が発生した場合に呼び出されるデリゲートをルーチンが受け入れることになります。多くの場合、デリゲートを渡すことは過度のことですが、デリゲートがどのようなパラメータを取るべきかを事前に決定することは難しいでしょうが、このアプローチは、混乱するかどうかの決定が外部要因。このような状況は通信シナリオで発生します。通信の問題への適切な対応は、プログラムに問題があることをユーザに通知し、ユーザが「キャンセル」を押すことを許可するが、プログラムに操作を再試行させるユーザがしなければ何回か。再試行しなければならない操作が実行されるべき操作全体のほんの一部であった場合、メインラインに例外を投げると、より大きな操作を「永久に」放棄し、ユーザーの介入なしに再試行を実行すると、ユーザーが知っている可能性のある操作をあきらめてコンピュータが諦めてしまうのは、(例えば、バッテリーが通信していたデバイスでちょうど死んでしまったため)コールバックデリゲートを使用すると、通信コードを特定のユーザーインターフェイスの実装に結びつけることなく、最適なユーザーインターフェイスを使用できます。

関連する問題