2

ライブラリにカスタム例外処理を実装して、例外が発生した場所を把握したいので、次のようにします。

try
{
    DoSomething();
}
catch(Exception ex)
{
    //LibraryException refers to any exception in the libraries exception hierarchy
    throw new LibraryException(ex.Message, ex);
}
  • これは避けるべきですか?

  • パフォーマンスに影響はありますか?

  • 例外をキャッチ、ネスト、および再スローすることの意味は何ですか?

4

5 に答える 5

4

唯一の潜在的な問題は、非固有の をキャッチしているため、例外処理ガイドラインExceptionに準拠していないことです。

次のいずれかが、これらのガイドラインにより適合します。

try
{
    DoSomething();
}
catch(SomeException ex)
{
    throw new LibraryException(ex.Message, ex);
}

また:

try
{
    DoSomething();
}
catch(Exception ex)
{
    if (ex is SomeException || ex is SomeOtherException)
    {
        throw new LibraryException(ex.Message, ex);
    }
    throw;
}

パフォーマンスに関しては、例外がスローされると、何か例外が発生したことになり、おそらくそれをラップすることによるわずかな追加のオーバーヘッドは気にならないでしょう。

コメントから:

ほとんどの場合、ライブラリが例外をラップすることを選択すると、ライブラリのスコープ外でスローされるすべての例外がラップされます...

主観的であることは認めますが、私はこれに同意しません。例外をラップするライブラリの 1 つの例は です。これはSqlMembershipProvider、いくつかの特定の例外を でラップしますProviderException

try
{
    new Regex(this._PasswordStrengthRegularExpression);
}
catch (ArgumentException exception)
{
    throw new ProviderException(exception.Message, exception);
}

ただし、呼び出し元が処理することが期待できないなどの他の例外SqlExceptionは、ラップされずに伝播されます。

于 2012-09-26T14:15:22.230 に答える
2

アーキテクチャに抽象化や明確さを追加する場合、これは良い習慣です。

これにより、例外がより明確になり、下位層の詳細が上位層から隠される可能性があります。たとえば、データアクセス層では、代わりにSqlExceptionsをキャッチしてDataAccessExceptionsをスローし、上位層がSQLServerをデータストアとして使用していることを「認識」しないようにすることができます。

于 2012-09-26T13:54:55.460 に答える
2

これは避けるべきですか?

それは好みの問題です。状況によっては有利になる場合もあれば、不利になる場合もあり、ほとんどの場合、両方の場合があります。これが既存のライブラリで行われている場合と、そうしないことを選択した他のライブラリがある場合があります。

パフォーマンスへの影響はありますか?

おそらくそうですが、それが本当に重要かどうかは疑問です。最初から決して安くはありません。

例外のキャッチ、ネスト、および再スローの意味は何ですか?

利点:

  • メソッドを呼び出す人は、ライブラリからスローされた例外を簡単にキャッチできます。
  • ライブラリの実装の詳細を呼び出し元から隠します。
  • 呼び出し元がライブラリから例外を簡単にキャッチできるようにします。これがないと、たとえば、無効な引数の例外をキャッチしようとすると、ライブラリまたは他のコードから発生する可能性があります。他の場所からスローされた引数の例外のみをキャッチしたい場合があります。

欠点:

  • ライブラリからスローされた可能性のある種類の例外の 1 つだけをキャッチし、他の例外をキャッチするのは困難です。
  • 例外テキストが表示されると、多くの混乱が生じます。
于 2012-09-26T13:56:06.373 に答える
1

わかりましたので、簡単な概要として、try catch ブロックで例外がキャッチされた場合、トレースのためにスタック全体を収集する必要があります。どのような種類の例外をスローしても、実際にはかなりコストがかかりますが、catch ブロック内にスローをネストすると、指数関数的に高くなります。したがって、例外をスローする理由が正確にわかっていて、try によって例外を処理する予定がある場合にのみ、例外をスローする必要があります。これは主に、API を作成していて、別の開発者がライブラリをどのように使用するかを予測できない場合に当てはまります。

独自のアプリケーション用に作成している場合は、(基本的に) 自分自身に例外をスローしているだけなので、例外をスローすることはまったく避ける必要があります。その場合、独自の例外をスローするのではなく、例外がスローされた場合に何が起こるかを処理する必要があります。

Python (私は好きですが、パラダイムが異なります) や他の "oops" 言語とは異なり、C# で例外処理を介してフローを制御することはお勧めできません。

C# では、try、throw、catch ブロックのパフォーマンス ヒットの程度

論理演算子としての try catch の使用に対する賛否両論

C# での例外処理

C# 例外 (これを確認してください)

CA1031:一般的な例外をキャッチしません

于 2012-09-26T13:57:49.897 に答える
1

状況に応じて、より具体的な例外をスローすることは、通常は良い考えです。ただし、LibraryException が独自の問題ドメインから発生し、より具体的な情報を開発者に提供して、開発者が「ああ、ライブラリ例外は、特定のクラスの 1 つを意味します。エラーが発生しました。」

try-catch は独自のパフォーマンス オーバーヘッドを課しますが、このブロックを他の同様のブロックよりも大幅に悪化させるものは何もありません。

于 2012-09-26T13:57:58.250 に答える