次のキャッチブロックの違いは何ですか?
try
{
...
}
catch
{
...
}
と
try
{
...
}
catch(Exception)
{
...
}
どちらの場合も、例外インスタンスは使用できないことに気付きましたが、一方で実行できることで、もう一方では実行できないことはありますか?
次のキャッチブロックの違いは何ですか?
try
{
...
}
catch
{
...
}
と
try
{
...
}
catch(Exception)
{
...
}
どちらの場合も、例外インスタンスは使用できないことに気付きましたが、一方で実行できることで、もう一方では実行できないことはありますか?
それらはほとんど同じです。
C#言語仕様のセクション8.10から:
一部のプログラミング言語は、System.Exceptionから派生したオブジェクトとして表現できない例外をサポートしている場合がありますが、そのような例外はC#コードでは生成できません。一般的なcatch句を使用して、このような例外をキャッチできます。したがって、一般的なcatch句は、タイプSystem.Exceptionを指定する句とは意味的に異なり、前者は他の言語からの例外もキャッチする可能性があります。
このブログで指摘されているように、C#は2つを区別しますが、実質的に.NET2.0と同じであることに注意してください。
2.0 CLRの最近の変更のおかげで、たとえばint(System.Int32)をどこかにスローすることを決定したコードがある場合、CLRはRuntimeWrappedExceptionでラップし、コンパイラーはそれを提供するように更新されました上記の2番目の句がデッドコードになったことを警告する
warning CS1058: A previous catch clause already catches all exceptions. All non-exceptions thrown will be wrapped in a System.Runtime.CompilerServices.RuntimeWrappedException
CLRがアセンブリに対してこのアクションを実行することをどのように認識しているかについては、コンパイラがRuntimeCompatibilityAttributeをアセンブリに追加して次のように指示していることに気付くでしょう。
.custom instance void [mscorlib]System.Runtime.CompilerServices.RuntimeCompatibilityAttribute::.ctor() = {property bool 'WrapNonExceptionThrows' = bool(true)}
catch
引数がないと、とは異なり、CLSに準拠していない例外がキャッチされますcatch (Exception)
。
言語が生成するMSILコードによっては、空のcatchステートメントも同様に悪い場合があります。C#は、空のcatchステートメントをcatch(System.Object)に変換します。これは、CLSに準拠していない例外も含め、すべての例外をキャッチすることになることを意味します。VBの方が動作が良く、空のcatchステートメントをSystem.Exceptionとしてcatch eに変換します。これにより、CLS準拠の例外のキャッチに制限されます。
生成されたILを見ると、違いは次のとおりです。
catch(Exception){}:
catch [mscorlib]System.Exception
{}
そして単なるキャッチ:
catch{}:
catch [mscorlib]System.Object
{}
したがって、理論的には、System.Exceptionから継承しない例外を持つことができる言語を作成すると、違いが生じます...
非CLS準拠言語(C ++ / CLIなど)は、System.Exceptionクラスから派生していないオブジェクトをスローする可能性があります。最初のコードサンプルでは、catchブロックでコードを実行できますが、スローされたオブジェクト自体を調べることはできません。これが問題になることはほとんどありませんが、問題になる可能性があります。
違いはないと思います。Resharperのようなツールは、他の例外条件に別の例外処理ロジックを適用する前に他の例外処理ブロックcatch(Exception)
も挿入しない限り、2番目のインスタンスでは冗長であると通知します。catch(SomeSubclassException)
Exception