- ベストアンサー
C# 例外が発生しないことの保障
Javaと比較して書きます。 Javaで記述した場合: public class JavaClass { public static SampleClass s = new SampleClass(); } C#で記述した場合: public class CSharpClass { public static SampleClass s = new SampleClass(); } JavaでもC#でも、同じコードを記述しているように見えますが、Javaではnew SampleClass()コンストラクタで例外が発生しない事が分かっているのに対して、C#の場合では例外が発生しないとは言い切れません。 これは、Javaでは、例外をスローする可能性のあるメソッド宣言では、その全てについてthrows宣言をしなければいけないのに対して、C#にはこの制約が存在しないことが原因です。 これについて何が困るかといいますと、C#で、static宣言な変数や静的コンストラクタで安易にメソッド呼び出し等を行うと、キャッチできなくなってしまいます。 public class Exceptionner { public Exceptionner() { throw new ApplicationException("Exceptionnerクラスの例外"); } } public class SampleClass { public static Exceptionner e = new Exceptionner(); // ここで例外が発生するが、キャッチできない。 } public class MyEntryPoint { public static void Main() { try { SampleClass s = new SampleClass(); } catch (Exception e) { // System.ApplicationExceptionでなくSystem.TypeInitializationExceptionとなる。 // つまり、元の例外の情報は失われている Console.WriteLine(e.GetType()); } } } これを現在漠然と問題視していますが、何かよい解決策はありませんでしょうか。 望んでいる解決策: ・C#でもメソッドが例外を返さないという保障がソースレベルでメソッドやコンストラクタに宣言可能? ・C#では例外をちゃんとキャッチしなくてもスマートに記述することが可能? ・問題視する必要がない?(whyも含めて)
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
そもそも、Java の検査例外って使いやすいですかね? 手前味噌ですが、例外についてのエントリです。 http://d.hatena.ne.jp/bleis-tift/20090809/1249825777 で、望まれている解決策ですが、 1 番目は「ない」です。 2 番目は、catch されなかった例外を処理するための仕組みがあるため、それを使用します。 例えば、AppDomain.UnhandledException や、Application.ThreadException、Application_Error ハンドラなどを使用します。 3 番目は、「問題視する必要がないなんて言えない」でしょう。 例外が起きたときの対処方法は、「何もしない」ことを選択したとしても、考える必要はあります。 「何を考える必要があるか」は上で紹介したエントリを参考にしてください。 例外・・・難しいですよね。
その他の回答 (2)
- rinkun
- ベストアンサー率44% (706/1571)
問題視する必要はない。ようです(^-^;)。 1. Javaでも実行時例外(RuntimeException)は発生する可能性がある。 Exceptionはthrows句の記述がないと発生できませんが、RuntimeExceptionは 関係なく発生する可能性があります。 2. C#の例外処理は本来Javaの実行時例外に相当するものを扱う。 逆にC#ではJavaのような発生可能性を宣言するタイプの例外は扱わず そういうものは例外ではなく返値として返すのが基本です。 # C#は使ったことがないので詳細は知りません
お礼
そうですよね。 1について RuntimeExceptionはcatchしなくてもコンパイル時点では気づかないこともありますよね。 2について bleisさんの参照リンク先の、「例外を使わなくても正常動作するプログラムを作成する」ために必要なことですね。 だんだんとC#のほうが正しいのかと思えてきました。
- Yune-Kichi
- ベストアンサー率74% (465/626)
ちょっと前に回答した物がありますので,まずはこちらを参照してみてください。 簡単に言うと,「Javaと.NET Frameworkでは例外に対しての考え方が違う」です。 QA: 5185119 http://okwave.jp/qa5185119.html > ・C#でもメソッドが例外を返さないという保障がソースレベルでメソッドやコンストラクタに宣言可能? できません (Javaでもできないけど……RuntimeExceptionとかErrorとか)。 > ・C#では例外をちゃんとキャッチしなくてもスマートに記述することが可能? > ・問題視する必要がない?(whyも含めて) そもそも,例外をcatchする状況って非常に限られますが……。 Site: むやみにキャッチしないでね。ゴールキーパー以外はハンドで反則ですよ。 - NAL-6295の舌先三寸 http://d.hatena.ne.jp/NAL-6295/20050909/p1 あと, > // System.ApplicationExceptionでなくSystem.TypeInitializationExceptionとなる。 > // つまり、元の例外の情報は失われている ですが,これは認識が誤っており,情報は残っています。 MSDN: TypeInitializationException クラス (System) http://msdn.microsoft.com/ja-jp/library/system.typeinitializationexception.aspx >TypeInitializationException の InnerException プロパティは、その発生原因である例外を保持します。 RemotingException等でも起こりえるので,Exception.InnerExceptionもちゃんと調べた方がよいです。 MSDN: Exception.InnerException プロパティ (System) http://msdn.microsoft.com/ja-jp/library/system.exception.innerexception.aspx
お礼
前半の内容については、先の2人の内容とおおまかにいうと同じですね。(そう解釈しました) やはりそれが正しいと認識したほうがよさそうです。 で、後半の内容については、(System.TypeInitializationExceptionをよく調べなかったのがいけなかったのですが)うれしい内容でした。 C#のコーディングのしかたのイメージがつかめてきました。 みなさんありがとうございました。
お礼
ありがとうございます。 確かに、Javaでは少々、例外に頼りすぎていた所もあったかもしれません。 が、Javaの標準ライブラリ自体がそういう書き方をしていることも事実なので、その言語の慣習の問題でもあるんでしょうね。 JavaからC#に言語を変えたら、また慣習も習得しなおす必要がありそうです。 AppDomain.UnhandledExceptionやApplication.ThreadException等の存在は知りませんでした。 これらについてはじっくり検証する必要がありそうです。