
C#でout修飾子で変数を別関数に投げ、呼んだ関数でファイル読み込みし、読み込みデータを関数内でオブジェクトを作らずにout修飾子変数に代入して処理終了する場合、呼び出し元側でもOutOfMemoryは出るでしょうか?
出るとすれば呼び出し先なら、呼び出し元にcatchのOutOfMemoryは置かなくても?と思っているところです。
いつなったかによる、などありましたら、詳細を頂けると助かります。
例)
class class1{
public void main(){
string data;
read(out data);
}
public void read(out string data){
data = File.WriteAllText("input.txt");
}
}
No.2ベストアンサー
- 回答日時:
どこでキャッチするかだけであって、スタックトレース見れば発生元まで追えると思います。
ログ情報で『○○関数開始』と出力後、read()内で当該例外になった時、
例外をmain()内でキャッチし、エラーメッセージおよびスタックトレースをログ出力すればいいのでは。
それは別に誤った情報にはなりませんよね。
個別にやるべきことがない場合、階層が深いメソッド内で例外をキャッチすると、
その都度必要な実装を書かなければならないことになり、煩雑になるかと思います。
何が何でも様々な例外においてその場ですべてキャッチし、個別に例外処理をするんだ!
という思想ならそれまでですが。
先に最も正解かと思う実装を記しますと、そもそも下層ではキャッチしない、となります。
class class1{
public void main(){
try {
string data;
read(out data);
} catch(OutOfMemoryException e) {
// OutOfMemoryException共通の処理
// Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace);
} catch(Exception e) {
// 共通の例外処理
// Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace);
}
}
public void read(out string data){
data = File.WriteAllText("input.txt");
}
}
OutOfMemoryException自体、いつどこで発生するか分からないという想定外の例外かと思います。
それをわざわざありとあらゆるところでキャッチするというのは明らかに非効率でしょう。
よって、ほとんどの場合でこれが正解かと思います。
例えばファイルがオープンできなかったとか、そういう業務的な例外は、その都度キャッチして、更に上位に例外を返す方法が正解かと思います。
(下記コードは例にあるコードに付け加えただけなのでテキトーです)
class class1{
public void main(){
try {
string data;
read(out data);
} catch(OutOfMemoryException e) {
// OutOfMemoryException共通の処理
// Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace);
} catch(Exception e) {
// 共通の例外処理
// Console.WriteLine(e.Message + Environment.NewLine + e.StackTrace);
}
}
public void read(out string data){
try {
data = File.WriteAllText("input.txt");
} catch(FileNotFoundException e) {
// ファイルが開けなかった際の個別処理
throw;
}
}
}
===================================
以下、パターンごとの考察となります。
1.
OutOfMemoryExceptionのキャッチをどっちにも入れるという方がどうかと思います。
class class1{
public void main(){
try {
string data;
read(out data);
} catch(OutOfMemoryException e) {
// なんか処理
}
}
public void read(out string data){
try {
data = File.WriteAllText("input.txt");
} catch(OutOfMemoryException e) {
// ログ出力処理
}
}
}
例えばこのような実装があった時、read()で例外が発生したとしましょう。
例外が発生したことをmain()は理解しませんので、そのまま処理を継続してしまいますよね。
絶対そこでめんどくさいことをしなければならなくなります。
エラー情報も戻り値を持つだとか、実際は不必要な実装など。
このような実装をすると、main()では、あくまでもmain()内でOutOfMemoryExceptionが発生した時しか例外をキャッチしなくなります。
2.
ではread()をこうしてみましょうか。
public void read(out string data){
try {
data = File.WriteAllText("input.txt");
} catch(OutOfMemoryException e) {
// なんか固有のログ出力
throw e;
}
}
}
こうすると今度は、read()内で発生した例外を、新たな例外情報として呼び元に返すことになります。
よって、スタックトレースとしては、例外が発生した直前のトレース情報しか得られなくなります。
これは、メソッドの階層が深くなればなるほど、どこで発生したのが分からなくなります。
3.
個別の処理が必要で、どっちにも入れる場合、最初に述べた通り、以下のようにして、スタック情報をすべて有している例外を最上位でキャッチすべきかと思います。
その場合、最上位は、OutOfMemoryExceptionだからどうのとかってあまりないかと思います。
(どうしても他の例外と処理を分ける必要があるならしてもいいですが)
class class1{
public void main(){
try {
string data;
read(out data);
} catch(Exception e) {
// 共通の例外処理
}
}
public void read(out string data){
try {
data = File.WriteAllText("input.txt");
} catch(OutOfMemoryException e) {
// なんか固有のログ出力
throw;
}
}
}
でもこの場合、OutMemoryException自体、いつ発生するかもわからないのですから、ありとあらゆる場所でOutOfMemoryExceptionをキャッチしてログ出力しなければならないというとても煩雑なことになるかと思います。
回答ありがとうございます。
スタックトレースのいうものを知りませんでした。
その他、案をいくつもお出し頂きありがとうございます。
確かにライブラリ関数でそもそも出る例外が予想されるもの(FileNotFoundなど)ならともかくとして、OutOfMemoryのような発生場所があやしいものを、ピンポイントで例外を置いたり、複数箇所に置くのはあまり利口な方法ではないことが理解できました。
main関数にOutOfMemoryExceptionのようなどこでも出そう系例外と、想定外エラー用にExceptionを置いて、呼び出し先関数には使用する関数に紐付くエラーを置くようにします。
※例外時にパラメータチェック用にブレイクかけたいので、細々したものは呼び出し先とします。
助かりました。
ありがとうございました。
No.1
- 回答日時:
例外処理を一切書いてないのだから、最終的な例外をスローする場所は呼び出し元に帰結します。
どのメソッドにコードを書いているから、どのメソッドで発生するとかじゃないです。
呼び先メソッドで例外が発生して、そのメソッドでキャッチしてないなら呼び元までスローされます。
すみません。
質問意図を伝えきれていませんでした。
try-catchはログ出しなどで例外発生関数が分かるように発生想定場所に置きたかったので、例の内容でcatch(OutOfMemoryException)を置くならどっち?というのを聞きたかった次第です。
そのため、例にはtry-catchを入れていません。
ログには関数開始時に「○○関数開始」と入れ、catch内に例外メッセージを書くので、呼び出し元に置いて、呼び出し先に置かず、呼び出し元で発生してると、ログでは発生したのが呼び出し元と誤った情報が記録されます。
どっちにも入れとけばいいじゃん、と言えばそれまでなのですが、後学のためにも、発生ポイントを知っておきたかった次第です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
今、見られている記事はコレ!
-
弁護士が解説!あなたの声を行政に届ける「パブリックコメント」制度のすべて
社会に対する意見や不満、疑問。それを発信する場所は、SNSやブログ、そしてニュースサイトのコメント欄など多岐にわたる。教えて!gooでも「ヤフコメ民について」というタイトルのトピックがあり、この投稿の通り、...
-
弁護士が語る「合法と違法を分けるオンラインカジノのシンプルな線引き」
「お金を賭けたら違法です」ーーこう答えたのは富士見坂法律事務所の井上義之弁護士。オンラインカジノが違法となるかどうかの基準は、このように非常にシンプルである。しかし2025年にはいって、違法賭博事件が相次...
-
釣りと密漁の違いは?知らなかったでは済まされない?事前にできることは?
知らなかったでは済まされないのが法律の世界であるが、全てを知ってから何かをするには少々手間がかかるし、最悪始めることすらできずに終わってしまうこともあり得る。教えてgooでも「釣りと密漁の境目はどこです...
-
カスハラとクレームの違いは?カスハラの法的責任は?企業がとるべき対応は?
東京都が、客からの迷惑行為などを称した「カスタマーハラスメント」、いわゆる「カスハラ」の防止を目的とした条例を、全国で初めて成立させた。条例に罰則はなく、2025年4月1日から施行される。 この動きは自治体...
-
なぜ批判コメントをするの?その心理と向き合い方をカウンセラーにきいた!
今や生活に必要不可欠となったインターネット。手軽に情報を得られるだけでなく、ネットを介したコミュニケーションも一般的となった。それと同時に顕在化しているのが、他者に対する辛らつな意見だ。ネットニュース...
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PC内で速度を遅くした音源をCD...
-
EXCELマクロでのtifファイルの...
-
flash (.swf) を編集したい
-
拡張子「.IDJ」を、windo...
-
デジカメでのマイクロSDのアダ...
-
複数のブックを新しいブックのS...
-
エフェクトはどうやって作りま...
-
TextBoxにフォーカスを与えると...
-
A4の紙に印刷されている文字を...
-
フォルダ内の複数のファイル形...
-
スマホでtxtファイルを編集する...
-
リストビューの選択状態を取得...
-
ホームページビルダーのプレビ...
-
GIMP separate+プラグイン クラ...
-
2枚、マイクロSDカードを入...
-
ExcelからCSVへウムラウトなど...
-
個別に違う添付ファイルを付け...
-
ドアスコープへの取り付けに向...
-
e-taxで送信ファイルの拡張子が...
-
ファミコンソフトの裏に書いた...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
個別に違う添付ファイルを付け...
-
e-taxで送信ファイルの拡張子が...
-
PC内で速度を遅くした音源をCD...
-
複数のブックを新しいブックのS...
-
A4の紙に印刷されている文字を...
-
エクセルで「特定の文字を含む...
-
スマホでtxtファイルを編集する...
-
拡張子「.IDJ」を、windo...
-
eclipseでタブ入力ができなくな...
-
iPhoneの内蔵の記憶媒体は、HDD...
-
GIMP separate+プラグイン クラ...
-
TextBoxにフォーカスを与えると...
-
ファイル数と合計サイズの取得方法
-
リストビューの選択状態を取得...
-
クラリスインパクトに替わるソ...
-
ビデオファイルのプロパティの...
-
エアコンの冷媒 R410Aの重...
-
VBA:カウンターの i の値が開放...
-
Fortniteのクラッシュについて
-
garagebandのLR Mixの方法について
おすすめ情報