C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[11]: 例外処理の動きやInnerExceptionについて


(過去ログ 109 を表示中)

[トピック内 12 記事 (1 - 12 表示)]  << 0 >>

■64621 / inTopicNo.1)  例外処理の動きやInnerExceptionについて
  
□投稿者/ 悩み多きランナー (9回)-(2012/12/12(Wed) 00:56:51)

分類:[C#] 

2012/12/12(Wed) 01:04:14 編集(投稿者)

C#における例外処理について下記のプログラムにおける
下記質問の回答をお願い致します。
<質問@>
(*1)についてSystem.ApplicationExceptionを削除し派生クラスにしないとビルドエラーになりますが
派生させないといけないということを単に覚えておくだけでよいのでしょうか?
またコンストラクタの定義で: base("BbException : " + msg)や: base(msg, inner)は何を
指すのでしょうか?

<質問A>
(*3)で"CallExceptionでエラーが出ました"の文字列と例外オブジェクトのeを
(*2)のコンストラクタに渡してますが、こうすることで
(*3)のBbException型のe2オブジェクトのmessageプロパティには
"CallExceptionでエラーが出ました"の内容が格納されInnerExceptionプロパティで
(*3)を発生させる原因になった(*4)のメッセージが格納されるという認識で
よいのでしょうか?

<質問B>
Exception.InnerExceptionは現在の例外を発生させた Exception インスタンスを取得と
目にしましたが、それは(*2)と(*3)の書き方をすることでExceptionインスタンスが
Exception.InnerExceptionプロパティに格納されるということでしょうか?
このように記述することで現在の例外を発生させた Exception インスタンスが格納
されることがイメージしにくいのでお手数ですが解説の程よろしくお願い致します。

class BbException : System.ApplicationException (*1)
{
public BbException(string msg)
: base("BbException : " + msg)
{
}
// innerException を使う用。
public BbException(string msg, Exception inner) (*2)
: base(msg, inner)
{
}

}
------------------------------------------------------------
class MyException
{
public void Test()
{
Console.WriteLine("Test() : メソッドが呼ばれました。");

throw new BbException("エラーが出ました");      (*4)
}

public void CallException()
{
try
{
this.Test();
}
catch (Exception e)
{
BbException e2 = new BbException("CallExceptionでエラーが出ました", e); (*3)
throw e2;
}
}

}
-----------------------------------------------------
static void Main(string[] args)
{
try
{
MyException me = new MyException();
Console.WriteLine("try : メソッドの呼出し");

// Test2 を呼んでみる。
me.CallException();
Console.WriteLine("try : メソッドの終了");
}
catch (BbException e)
{
// BbException
Console.WriteLine("catch( BbException e) : BbException がスローされた! ");
Console.WriteLine("catch( BbException e) : {0}", e.Message);
Exception inner = e.InnerException;
if (inner != null)
{
Console.WriteLine("catch( BbException e) : InnerException : {0}", inner.Message);
}
}
catch (Exception e)
{
// Exception は全ての例外をキャッチします!
Console.WriteLine("catch( Exception e) : エラーがスローされた.");
Console.WriteLine("catch( Exception e) : {0}", e.Message);
}
finally
{
Console.WriteLine("finally : try catch の全ての処理後に呼ばれます。");
Console.ReadLine();
}

}
引用返信 編集キー/
■64623 / inTopicNo.2)  Re[1]: 例外処理の動きやInnerExceptionについて
□投稿者/ shu (128回)-(2012/12/12(Wed) 10:35:00)
No64621 (悩み多きランナー さん) に返信

例外の話よりまず派生について理解されていますでしょうか?

ExceptionのコンストラクタについてMSDNより
http://msdn.microsoft.com/ja-jp/library/804f22sf(v=vs.80).aspx

この辺を理解されれば今回の質問は解決すると思います。
引用返信 編集キー/
■64624 / inTopicNo.3)  Re[2]: 例外処理の動きやInnerExceptionについて
□投稿者/ howling (140回)-(2012/12/12(Wed) 10:54:24)
No64621 (悩み多きランナー さん) に返信

例外については、私も深く考えたことが無かったのですが…、

新規に作ったクラスを、例外を処理するクラスにするには、どうすればいいのか?
ということを考えると、
例外を処理する基底クラス(これがExceptionクラスなんでしょうね)を継承することで、
「これは例外を処理するクラスですよ」ということを指し示しているんだと思います。

だからこそ、よくある例外処理の形として、

try
{
//例外の出る可能性のあるコード
}
catch(MyException MyExcep) //指定した何かの例外(ここではMyException)が起きた時の処理
{
//例外処理
}
catch(Exception ex) //その他の例外
{
//種類を問わず、例外は何でも引っかかる様子
}

こんなのがあるのかなと思いました。
なるほど、それならcatch(Exception)としておけば、必ず例外は引っかかるわけだ…。
だって基底クラスなんですもんね…なるほど納得。

しかし、Exception自体はinterfaceクラスなのかと思っていたのですが、そうではないんですね。
catchする時にコンストラクタが呼ばれるのかな…?
今度試してみようかな。
引用返信 編集キー/
■64629 / inTopicNo.4)  Re[3]: 例外処理の動きやInnerExceptionについて
□投稿者/ 774RR (34回)-(2012/12/12(Wed) 12:06:22)
> catchする時にコンストラクタが呼ばれるのかな…?
値型と参照型の違い、って奴だよね。

throw するときに new するのはしかたない
catch するときに(コピー)コンストラクトされると *それが* 例外原因になりえる=ダメ!
catch するときにはコピー操作が発生しないよう参照で受け取るべし

C# の場合、値型は禁止で参照型は許可、っつこと。


引用返信 編集キー/
■64630 / inTopicNo.5)  Re[4]: 例外処理の動きやInnerExceptionについて
□投稿者/ howling (142回)-(2012/12/12(Wed) 12:22:22)
No64629 (774RR さん) に返信
あー!あーあーあー!そういうことか!

そういえば、throw new MyExceptionみたいに書きますね…。
そこでnewしているのか…。
おっしゃる通りクラスは参照型ですから、
catchするだけならnewする必要性って無いんじゃないか?とか思っていたので、
納得できました…。

インスタンスの作成自体が例外原因になる…とかまでは考えたこと無かったです。
確かにそう考えると、できるだけ何もしないで渡すのが正しいですね。
おかげさまでスッキリしました。
灯台もと暗しですね…(苦笑
普段例外をcatchするばかりで、throwしていないからこうなるんだなぁ…。
引用返信 編集キー/
■64631 / inTopicNo.6)  Re[5]: 例外処理の動きやInnerExceptionについて
□投稿者/ shu (130回)-(2012/12/12(Wed) 12:53:21)
No64630 (howling さん) に返信

> catchするだけならnewする必要性って無いんじゃないか?とか思っていたので、
> 納得できました…。
new Exceptionで例外情報を作成して
throwで例外を実際に発生させるわけです。
発生していない例外をcatchすることは出来ないしcatchする時点で例外は発生している
のでcatchでインスタンスが出来るのは変なのです。
引用返信 編集キー/
■64632 / inTopicNo.7)  Re[6]: 例外処理の動きやInnerExceptionについて
□投稿者/ howling (143回)-(2012/12/12(Wed) 13:00:52)
No64631 (shu さん) に返信
> new Exceptionで例外情報を作成して
> throwで例外を実際に発生させるわけです。
> 発生していない例外をcatchすることは出来ないしcatchする時点で例外は発生している
> のでcatchでインスタンスが出来るのは変なのです。

ですよね…。
なんでinterfaceクラスにしないんだろう?とだけ思っていましたので。
ん…?でも、必ずExceptionから継承したクラスしかthrowできない、としてやれば、
Exceptionクラス自体はinterfaceつけてもいいのでは…?
まぁ、付けなくてもいいっちゃいいんですが…基本は継承されることを前提としているような気がします。>Exeptionクラス
なんででしょう?
引用返信 編集キー/
■64633 / inTopicNo.8)  Re[7]: 例外処理の動きやInnerExceptionについて
□投稿者/ shu (131回)-(2012/12/12(Wed) 13:13:32)
No64632 (howling さん) に返信
> ですよね…。
> なんでinterfaceクラスにしないんだろう?とだけ思っていましたので。
> ん…?でも、必ずExceptionから継承したクラスしかthrowできない、としてやれば、
throw出来ないです。

> Exceptionクラス自体はinterfaceつけてもいいのでは…?
> まぁ、付けなくてもいいっちゃいいんですが…基本は継承されることを前提としているような気がします。>Exeptionクラス
> なんででしょう?
継承とインターフェースの違いは分かりますか?

Exception にはこれだけ実装されたメンバーがあります。
http://msdn.microsoft.com/ja-jp/library/system.exception_members(v=vs.80).aspx

インターフェースにするとこれらの実装をしないといけなくなってしまいますよ。

引用返信 編集キー/
■64634 / inTopicNo.9)  Re[8]: 例外処理の動きやInnerExceptionについて
□投稿者/ howling (144回)-(2012/12/12(Wed) 14:06:54)
No64633 (shu さん) に返信
> 継承とインターフェースの違いは分かりますか?
>
> Exception にはこれだけ実装されたメンバーがあります。
> http://msdn.microsoft.com/ja-jp/library/system.exception_members(v=vs.80).aspx
>
> インターフェースにするとこれらの実装をしないといけなくなってしまいますよ。

なるほど、そういえばそうですね。
だからですか…。
さすがにこれだけの実装となると大変ですもんね。
だからほぼ実装しておいて、一部だけoverrideする感じにするんですね…。
いやはや、長々とすみません。自分が設計する場合の参考になりました。
ありがとうございました。
引用返信 編集キー/
■64642 / inTopicNo.10)  Re[9]: 例外処理の動きやInnerExceptionについて
□投稿者/ 悩み多きランナー (10回)-(2012/12/12(Wed) 23:31:39)
お世話になります。

いろいろとご解説ありがとうございます。
いくつか質問をしましたが、結局はExceptionクラスで提供されているコンストラクタを
定義することで第1引数のメッセージを初期化したり、例外を発生する原因となった例外のインスタンスの
初期化を行ったりしていたということですね。

またclass BbException : System.ApplicationException というふうに
定義してることについては.NET Frameworkが提供しているSystem.Exceptionクラスの
継承関係にあるSystem.ApplicationExceptionの機能をBbExceptionクラスに
継承させているという認識でよろしいですか??

ご教授よろしくお願い致します。
引用返信 編集キー/
■64643 / inTopicNo.11)  Re[10]: 例外処理の動きやInnerExceptionについて
□投稿者/ shu (132回)-(2012/12/13(Thu) 07:59:24)
No64642 (悩み多きランナー さん) に返信
> またclass BbException : System.ApplicationException というふうに
> 定義してることについては.NET Frameworkが提供しているSystem.Exceptionクラスの
> 継承関係にあるSystem.ApplicationExceptionの機能をBbExceptionクラスに
> 継承させているという認識でよろしいですか??
良いです。


引用返信 編集キー/
■64653 / inTopicNo.12)  Re[11]: 例外処理の動きやInnerExceptionについて
□投稿者/ 悩み多きランナー (11回)-(2012/12/13(Thu) 20:41:37)
No64643 (shu さん) に返信
> ■No64642 (悩み多きランナー さん) に返信
>>またclass BbException : System.ApplicationException というふうに
>>定義してることについては.NET Frameworkが提供しているSystem.Exceptionクラスの
>>継承関係にあるSystem.ApplicationExceptionの機能をBbExceptionクラスに
>>継承させているという認識でよろしいですか??
> 良いです。
>
>

お世話になります。

回答ありがとうございます。
いろいろわからないことがありましたが、皆さんが教えてくれた
おかけで大変勉強になりました。

ありがとうございます。
解決済み
引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -