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

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

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

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

例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

Q&A

解決済

2回答

885閲覧

C# throw文について

SHOSHINSHA

総合スコア1

C#

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

例外

例外(exception)とは、プログラムの処理実行中に発生する、通常の処理の続行を妨げる特殊な事象のことを呼びます。この「例外」が発生した場合に、現在の処理を中断し、変わりに別の処理を実行させる事を「例外処理」と呼びます。

例外処理

例外処理(Exception handling)とは、プログラム実行中に異常が発生した場合、通常フローから外れ、例外として別の処理を行うようにデザインされたプログラミング言語構造です。

0グッド

0クリップ

投稿2022/04/30 16:27

編集2022/05/01 11:49

意図的に例外を起こす為のthrowの使い方として、
参考書には下記の例が挙げられているのですが、3つ質問があります。
※「~省略~」としている箇所は参考書上でも実際に記載が省略されています。

①内側のtryの「エラーを含んだ処理」とは具体的にどんなものが入るのでしょうか。
②下記の例ではtry内に更にtry-catchを記載していますが、普通のtry-catchとの違いがよく分かりません。
③e1.Messageは読み取り専用とのエラーが出てしまいます。

よろしくお願いいたします。

try{ ~省略~ try{ ~省略~ ←エラーを含んだ処理 } catch (Exception e1) { Eception e1 = new Exception(); e1.Message = "エラー"; throw.e1; } } catch(Exception e2){ Console.WriteLine(e2.Message); }

2022/5/1 追記
上記のコードは実際に参考書に書いてあります・・・笑
随分ひどいようなので他の本を使おうと思います。
イメージ説明

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

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

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

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

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

Zuishin

2022/04/30 23:27 編集

① System.IO.File.ReadAllLines("aaaaa"); ② 内側で throw したものを catch するため ③ e1.Message には代入できないから とりあえずこの参考書はやめましょう。 本当にこんなのが売られていましたか? ろくでもないコードです。
退会済みユーザー

退会済みユーザー

2022/04/30 22:54

> 参考書には下記の例が挙げられているのですが 参考書の書籍名を教えてください。
退会済みユーザー

退会済みユーザー

2022/05/01 02:06

こういう本を売っているんですね。特に以下の部分は信じがたいほどメチャクチャなんですが、何かも勘違いとかはないですか? catch (Exception e1) { Eception e1 = new Exception(); e1.Message = "エラー"; throw.e1; }
退会済みユーザー

退会済みユーザー

2022/05/01 02:19 編集

> 2022/5/1 追記 > 上記のコードは実際に参考書に書いてあります・・・笑 > 随分ひどいようなので他の本を使おうと思います。 画像を拝見しました。それは例外処置の一般的・基本的な方法の説明とかではなくて、何か別のことを説明したくて、それが本文や赤い矢印で説明してあるのではないですか? たぶん、そこを質問者さんが理解でされてないような気がしますけど、違います? ・・・と思いましたけど、それでもやっぱり e1.Message = "エラー"; が変ですね。
SHOSHINSHA

2022/05/01 02:23

画像差し替えました。 ご確認お願いいたします。
guest

回答2

0

ベストアンサー

参考書には下記の例が挙げられているのですが、

どこの誰が書いたかもわからないネットの記事ならともかく、一般に販売されている書籍にそのようなこと書いてあることはないはずなので、このスレッドは釣りを疑うレベルですが・・・

質問に書いてあるコードは、はっきり言ってデタラメでそれをベースに議論できるレベルには無いので、自分が持っている Microsoft の本に質問のコードとよく似たものがあったのでそれをベースに説明します。

public bool InsertAuthors() { var connection = new SqlConnection("接続文字列"); var command = new SqlCommand("INSERT INTO authors VALUES ('172-32-1176', 'White', ...)", connection); try { connection.Open(); try { command.ExecuteNonQuery(); } catch(SqlException sqle) { if (sqle.Number == 2627) { return false; } else { throw; } } } finally { connection.Close(); } return true; }

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

①内側のtry

余計なものを catch しないよう、PK 制約違反が発生するコード一行のみを囲む。

②下記の例ではtry内に更にtry-catchを記載していますが

外側の try はどこで例外が発生しても必ず connection.Close(); に制御が飛んで接続リークを防止するため。内側の try は上に説明した通り。

③e1.Messageは読み取り専用とのエラーが出てしまいます。

質問のコードの内側の catch 内のコードはメチャクチャで議論の対象になるようなものではありません。Exception を catch することがあるとすると、例えば、原因不明の問題が発生していてその調査のためログを取るためぐらいでしょうか。ログを取ったら即 throw し、それをランタイムに拾わせてアプリケーションを停止させます。

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

(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

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

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

投稿2022/05/01 01:04

編集2022/05/01 02:49
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

SHOSHINSHA

2022/05/01 02:14

詳しく回答頂きありがとうございます。 SurferOnWwwさんの例のようなコードであれば、 「プログラム上問題がある動き(配列の範囲外など)」と、 「プログラム上は問題ないが、作成者側がエラーにしたい条件」を 分けて扱いたい為の処理ということが理解できます。 私の挙げた例は、参考書にあるぐらいだから何か意図があってこの形になっているのだろうと思いましたが、 みなさまの回答を見る限りそうではなさそうですね・・・。 その事が分かって良かったです。 ありがとうございました。
退会済みユーザー

退会済みユーザー

2022/05/01 02:49

本は「例外を意図的に起こしたいとき」の説明のようですけど、画像を見る限りでは説明が不適切だと思います。(百歩譲っても e1.Message = "エラー"; という間違いは問題外) 例として書くなら、あるインターフェイスを継承してクラスを書いたが、一部未実装なので、それを呼ばれたら NotImplementedException を throw して自爆するとかいうのはよく目にするので、それを書くとか。 public Task<IdentityResult> DeleteAsync(Role role, CancellationToken cancellationToken) { throw new NotImplementedException(); }
guest

0

  1. そりゃ例外を出す処理ですね
  2. 同じです。try節内の処理で例外が出ると、それに対応したcatch が呼び出されます
  3. そういうもんです

投稿2022/04/30 23:52

y_waiwai

総合スコア87719

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

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

退会済みユーザー

退会済みユーザー

2022/05/01 00:32

回答になってないのでマイナス評価。もしこれにベストアンサーを付けたら質問者さんもマイナス評価。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問