質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Q&A

解決済

3回答

2482閲覧

try-catch-finallyでのthrowの使い方

退会済みユーザー

退会済みユーザー

総合スコア0

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

0グッド

1クリップ

投稿2022/10/31 11:56

前提・実現したいこと

try-catch-finallyでのthrowの使い方の方法を知りたいです。

特にcatch内でthrowだけの場合何を実装しているかわからない。

該当のソースコード

C#

1try 2{ 3 例外が発生する可能性のあるコード 4} 5catch(例外の種類?) 6{ 7 例外発生処理コード 8throw; 9 10} 11finally 12{ 13 例外発生の有無にかかわらず実行したいコード 14}

試したこと

try-catch-finallyについて勉強して、
tryのカッコ内で例外が発生しているか判定しながらコードが進んでいき、
例外の場合は、実装することがわかった。

throwは例外を発生させしているときに使う、throwによって例外が発生させると書いているが、

catchのカッコ内ですでに例外を発生させしているのにthrowによって例外が発生させることがわからないです。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

BeatStar

2022/10/31 12:23

再送しているだけかと。 そのメソッドが呼ばれている場所に投げているはずです。
退会済みユーザー

退会済みユーザー

2022/10/31 12:28

> 再送しているだけかと 違いますよ
Zuishin

2022/10/31 13:47 編集

スローは投げる、キャッチは捕る、です。 投げた例外を捕まえるのが catch で、このブロック内で例外を分析し、その問題を解決します。 通常、例外はそこで消えます。 分析した上で処理しきれなかった場合には、同じ例外を再度スローして別のハンドラに処理を任せることができます。 これが throw です。 catch ブロック内で単に throw と書くと、捕まえた例外をそのまま何もなかったかのように再スローすることができます。 この質問のコードでは、キャッチした例外を何もせずそのまま投げているだけなので、全く無駄な処理になっていますが、本来ならこの throw の前に分析やログへの書き込みを行い、その後に throw します。 > 例外発生処理コード と書かれているところに、本来なら例外処理のコードを書きます。
guest

回答3

0

ベストアンサー

(既に述べられている話と同じなんだけど,納得されていない様子なので書いてみる.)

(1)
何か例外が発生する可能性がある処理があるとして…

C#

1//(try とか catch とか書いてない場合) 2 3if( 処理中に何かあったら )throw new XXXException();

ifの条件を満たしてXXXException が throw されたらどうなるのか?
…っていうのは,いいよね?

(2)
「せっかくだから俺は XXXException 例外が発生した場合には何か特別なことをしたいぜ!」という場合に,try だのをこんな感じに書くと…

C#

1try 2{ 3 if( 処理中に何かあったら )throw new XXXException(); 4} 5catch( XXXException ) 6{ 7 特別なことをする 8 //(ここで catch した例外は握りつぶされる) 9} 10 11//catch ブロックを抜けた後は何もなかったかのようにここにくる 12...

XXXException例外が投げられた場合にはcatchブロック内の「特別なこと」が実施されるんだけど,これだと XXXException 例外はそこで役目を終えて(よく「握りつぶされる」とか言うみたいね),以降,まるでその例外が発生しなかったかのように処理が進む.

(3)
で,「いやいや俺は(2)の場合のように XXXException 例外が発生した場合には何か特別なことをしたいんだけども,その後は,その例外をcatchしなかった(1)の場合のように物事が進んで欲しいぜ!」という場合に throw; って書く.

C#

1try 2{ 3 if( 処理中に何かあったら )throw new XXXException(); 4} 5catch( XXXException ) 6{ 7 特別なことをする 8 9 throw; //俺はこの catch した例外を握りつぶさないぜ! 10}

投稿2022/11/01 02:16

fana

総合スコア11663

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

特にcatch内でthrowだけの場合何を実装しているかわからない。

それはたぶん「例外発生処理コード」のところで補足した例外をログに残すとかして、その後 throw してアプリを終了しているのだろうと思いますす。

.NET アプリの例外処置について Microsoft Blog に書いてあったことを要約して紹介しておきます(Blog は今はリンク切れです)。

(1) 予測可能で正しい業務フローに戻すことができる「業務エラー」(例:ユーザーの入力間違い)と、予測できないもしくは予測はできても何の対応もできない「例外」(例:DB サーバーダウン)を区別して対処。

(2) 「例外」はランタイムに拾わせてアプリケーションを停止させる。無かったことにして、ユーザが作業を続けられるようにすると、強制的に停止させるより好ましからざる状況に陥るかも(ユーザーが大事なデータを壊したりとか)。

(3) よほどのことがない限り try-catch は書かない。

(4) キャッチせざるを得ない場合でも Execption はキャッチしない。範囲を絞る。例えば DB 関係の例外が予測されるなら SqlException に限定して catch し、Number プロパティなどでエラーの内容を調べて対処するとか。

(5) 間違って補足してしまった例外は throw する。(注:catch ブロックでキャッチした例外を throw するとスタックトレースが途切れるので単に throw と書く)

(6) ユーザーへの通知が必要なら、集約的例外処置を利用する。

それから、.NET 4 からは破損状態例外は catch できなくなっているそうですが、「それでも Catch (Exception e) を使用するのはよくない」ということについては以下の記事を見てください。

破損状態例外を処理する
https://docs.microsoft.com/ja-jp/archive/msdn-magazine/2009/february/clr-inside-out-handling-corrupted-state-exceptions

自分が持っている Microsoft の本に、上に書いた原則に則ったサンプルが載っていたので紹介しておきます。

データベースに INSERT する際に PK 制約違反で発生する例外のみ catch して「業務エラー」(2 重登録)としてユーザーに再入力を促し、その他は再 throw してランタイムに拾わせてアプリケーションを停止させるというものです。

C#

1public bool InsertAuthors() 2{ 3 var connection = new SqlConnection("接続文字列"); 4 var command = new SqlCommand("INSERT INTO authors VALUES ('172-32-1176', 'White', ...)", connection); 5 try 6 { 7 connection.Open(); 8 try 9 { 10 command.ExecuteNonQuery(); 11 } 12 catch(SqlException sqle) 13 { 14 if (sqle.Number == 2627) 15 { 16 return false; 17 } 18 else 19 { 20 throw; 21 } 22 } 23 } 24 finally 25 { 26 connection.Close(); 27 } 28 29 return true; 30}

以下の記事も参考になると思います。

例外の推奨事項
https://docs.microsoft.com/ja-jp/dotnet/standard/exceptions/best-practices-for-exceptions

投稿2022/10/31 12:26

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2022/10/31 13:01

すみません。 まだ、throwの使い方のついてわからないです。 特にthrowを行うことでどういう操作が実行させるか聞きたいです。 回答の解説を初心者向けにわかりやすくできますか?
退会済みユーザー

退会済みユーザー

2022/10/31 14:09 編集

> 回答の解説を初心者向けにわかりやすくできますか? いやいや、何を言ってるんですか。これが初心者向けの説明です。初心者でも分かるように十分に分かりやすく説明しているつもりなんですけど。 これが分からないというなら、分かるようになるまで自分で勉強してください。こういう文章でやり取りする掲示板では、あなたが話が通じる程度に必要最低限の知識を持ってないと話になりません。 もし、一から十まで手取り足取り優しく教えてもらえることを期待しているなら学校に行きましょう。それなら、講師があなたと Face-to-face でやり取りして、何が分からないのか言語化できるスキルがなくても、言葉の端々とか顔色とかから何が分からないのかを探ってもらえて、あなたが望む答えがもらえるかも。
vann_2921

2022/11/01 00:34

横から失礼します。 追記修正依頼のBeatStarさんのコメント「再送しているだけ」に対する「違います」の理由がこの回答では分かりませんでした。 あとこの回答はthrowの使い方であり、質問のコード上のthrowが何をしたいのかは説明されていないと思いました。 実際は書いた人にしか分からないですし回答としては推測にならざるを得ないのですが、SurferOnWwwさんは1~6の使い方のどれを質問者さんのコードが意図していると思いますか? 使い方の1~6のいずれかという回答でも間違いではないのですが、質問者が求めているものとはちょっとずれているように思いました。
退会済みユーザー

退会済みユーザー

2022/11/01 01:21

> 質問のコード上のthrowが何をしたいのかは説明されていないと思いました。 説明してますよ。 そもそも質問のコードが私の回答の (1) ~ (5) で書いたことに沿って書かれています。throw の部分だけ見ていても何の話か分からないと思いますよ。ストーリーを追わないと。
guest

0

特にcatch内でthrowだけの場合何を実装しているかわからない。

処理できなかった例外を投げなおす(上位にある別な例外処理ハンドラに委ねる、あるいはそのまま強制終了させる)ための構文です。

投稿2022/10/31 13:33

maisumakun

総合スコア145192

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2022/11/01 02:33

> catchのカッコ内ですでに例外を発生させしているのにthrowによって例外が発生させることがわからないです。 try内で発生した例外は、catchにより「いったん片付いた」形となっています。ただ、catchしたものの処理不能となった場合はなんとかしないといけないので、再スローを行います。 (処理できなかったから放置するという行為は、例外を握りつぶして、隠蔽するような形となってしまうので、「例外処理すらしない」のが正しいという、大域脱出に例外を使うような場合を除いてやるべきではありません)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問