22

Throwしたがって、好奇心から、標準クラスでは使用できないのに対し、キーワードで使用できるようにする例外クラスの特別な点を確認したかったのです。

私が見つけたのは、例外クラスが次を実装したことだけです

public class Exception : System.Object, System.Runtime.Serialization.ISerializable, System.Runtime.InteropServices._Exception
{
}

そのため、同じインターフェイスを実装して、派生していない独自のカスタム例外をスローしようとしましたがSystem.Exception、役に立ちませんでした。と忠告されただけ

キャッチまたはスローされた型は、から派生する必要がありますSystem.Exception

では、これには何か特別な理由があるのでしょうか。マネージド言語の選択肢はほとんどなく、恣意的であるように思われると思います。

4

6 に答える 6

24

あなたの前提は間違っていると思います。から派生していないオブジェクトがスローされる可能性がありますSystem.Exception。C# でスローしたり、catch 句でオブジェクトを調べたりすることはできません。C# 仕様 (v4.0) のセクション 8.10 から:

一部のプログラミング言語は、System.Exception から派生したオブジェクトとして表現できない例外をサポートする場合がありますが、そのような例外は C# コードでは生成できません。一般的な catch 句を使用して、そのような例外をキャッチできます。したがって、一般的な catch 句は、型 System.Exception を指定するものとは意味的に異なります。前者は、他の言語からの例外もキャッチする可能性があります。

一般的なキャッチの例:

try
{
}
catch (Exception) { } // 'specific' catch
catch { } // 'general' catch

特に、これはアンマネージ コードを呼び出すときに重要です。

一部の型は、すべての言語で常に特別な扱いを受けるようです。ほとんどの場合、それらはシステムにとって非常に基本的なものだからです。System.ExceptionSystem.ValueTypeSystem.Delegateはすべて C# の特殊な型であり、言語キーワードと CLR に密接に結び付けられているため、それらの役割を引き継ぐクラスを単に実装できないのは驚くことではありません。

于 2012-09-27T07:01:18.100 に答える
10

例外の設計ガイドライン

例外は、エラーを報告するための標準的なメカニズムです。アプリケーションとライブラリは、リターン コードを使用してエラーを伝えるべきではありません。例外を使用すると、一貫したフレームワーク設計が追加され、戻り値の型を持つことができないメンバー (コンストラクターなど) からのエラー報告が可能になります。

スロー (C# リファレンス)

次の例に示すように、スローされた例外は、クラスが System.Exception から派生したオブジェクトです。

class MyException : System.Exception {}
// ...
throw new MyException();

例外の概要

.NET Framework では、例外は Exception クラスから継承するオブジェクトです。

したがって、例外は から派生する必要がありますSystem.Exceptionが、それをどのように整理するかはあなた次第です。

于 2012-09-27T03:57:35.837 に答える
4

これは、CLS の設計者の任意の選択です。おそらく、彼らは一貫性の理由からこの選択をしたのでしょう。C# は CLS に従います。この要件は、例外タイプの実装に関連する技術的な理由ではなく、この理由でコンパイラによって強制されます。

CLI は実際に任意のオブジェクトをスローできます。http://jilc.sourceforge.net/ecma_p3_cil.shtml#_Toc524462405を参照してください。

于 2012-09-27T05:59:28.313 に答える
4

言語はSystem.Exception、すべての例外のベースとして使用します。これは本質的に、スロー可能またはキャッチ可能な例外が発生した場合にエラーが発生しないことを意味します(Exception)myExc。これはおそらく、System.Exceptionすべての例外が同じインターフェイスに準拠するようにクラスの定義が使用されているためです。インターフェースが一貫しているため、例外はスタック トレースと意味のあるメッセージ (たとえば) と共に到着します。これは、ログ記録にとって非常に重要です。

于 2012-09-27T03:52:51.757 に答える
3

すべての例外にユニバーサル基本クラスが必要な理由の 1 つは、単一の catch ブロックですべての種類の例外をキャッチできるようにするためです。

私がこれを持っている場合:

try
{
    ...
}
catch(Exception ex)
{
    // Handle somehow
}

これにより、すべての例外がキャッチされ、それが何であるかを (を使用してex.Message) 表示できるようになります。

何かを投げることができる場合、すべてをキャッチし、投げられたオブジェクトにアクセスできるようにするキャッチをどのように作成しますか?

あなたは絶対にすべてをキャッチするこれを持つことができます:

try
{
    ...
}
catch
{
    // Handle somehow
}

しかし、あなたは投げられたものを「失った」のです。

于 2012-09-27T06:11:41.437 に答える
0

「システム」を参照として追加して解決しました

try
{
}
catch (System.Exception) {}
于 2020-06-08T07:09:13.297 に答える