16

私は現在ソリューションを開発しており、戦略/プロバイダー パターンを強力に実装するように設計しました。そのため、このソリューションは多数のインターフェイスを公開し、これらのインターフェイスのデフォルトの実装を含みます。これらのインターフェイスは、DI タイプの方法論で置き換えることができます。

ホスト アプリケーションがこれらのインターフェイスを多数使用する場合、発生する可能性のある特定の例外を処理することが期待されます。たとえば、IDataRetrieverインターフェイスにはメソッドがあり、ホストはやSomeDataType GetData(int timeout);などのカスタム例外を処理できます。 DataRetrievalTimeoutExceptionNetworkConnectionException

私の質問は、開発者がそれを実装するときに、特定の例外がスローされ、ホストによって処理されることがわかるように、インターフェイス クラスをマークアップする最良の方法は何ですか?

現時点では、メソッドの xml コメントに例外 xml タグを追加したところですが、これで十分でしょうか?

4

6 に答える 6

13

XML タグ (および作成したいその他のドキュメント) は、基本的に現時点で「バニラ」.NET に最も近いものです。

例外、前提条件などを含めることができるコントラクトでインターフェイスに注釈を付けることができるCode Contractsを見たいと思うかもしれません。

于 2010-10-13T11:50:50.400 に答える
3

インターフェイスではできません。基本クラスでできます。

public interface IFoo
{    
  /// <summary>
  /// Lol
  /// </summary>
  /// <exception cref="FubarException">Thrown when <paramref name="lol"> 
  /// is <c>null</c></exception>
  /// <remarks>Implementors, pretty please throw FE on lol 
  /// being null kthx</remarks>
  void Bar(object lol);
}

対。

public abstract BaseFoo
{    
  /// <summary>
  /// Lol
  /// </summary>
  /// <exception cref="FubarException">Thrown when <paramref name="lol"> 
  /// is <c>null</c></exception>
  public void Bar(object lol)
  {
    if(lol == null)
      throw new FubarException();
    InnerBar(lol);
  }

  /// <summary>
  /// Handles execution of <see cref="Bar" />.
  /// </summary>
  /// <remarks><paramref name="lol"> is guaranteed non-<c>null</c>.</remarks>
  protected abstract void InnerBar(object lol);
}
于 2010-10-13T12:09:19.270 に答える
2

インターフェイス内で例外クラスを定義し、CPU が燃えているか、その他のそのような劇的な状況が存在しない限り、例外クラスから派生しない例外をエスケープすることを許可しないように指定することをお勧めします (その場合でも、を明示的に定義IWoozle.SystemCorruptionExceptionして、ポケモン ハンドラが単純に例外をキャッチし、ログに記録し、スローした場合、少なくとも誰かが例外が重要であると考えたことをログが反映するようにします)。

カスタム例外タイプを定義しないようにするという Microsoft の推奨事項は残念だと思います。これは、基になるコレクションが列挙中に変更されIEnumerator<T>.MoveNext()たために がスローされるのか、または の内部処理が に遭遇し、単にバブルアップするのかを明確に区別する方法がないことを意味するためです。呼び出し元に。代わりに、前者のケースでanをスローした場合、エスケープされたものは後者のケースを表す必要があります。InvalidOperationExceptionIEnumerator<T>.MoveNext()InvalidOperationExceptionIEnumerator<T>.MoveNext()IEnumerator.InvalidatedEnumeratorExceptionInvalidOperationException

于 2012-02-02T16:55:25.033 に答える
1

これは、インターフェイスを実装するクラスに依存するべきではありませんか?

たとえば、インターフェイスを取得し、GetDataメソッドを使用して独自のクラスを実装すると、どこからでもデータを「取得」できます。それがWebサービスだったとすると、スローされる可能性のある例外のタイプは、ローカルファイルシステムからデータを「取得」している場合とは異なる可能性があります。

したがって、私の実装では、実装に固有の例外を実装(および文書化)して、実装を使用しているコードがそれらを処理できるようにします。これらの例外の処理方法は、実装に非常に固有である可能性があります。たとえば、デスクトップアプリではなく、Webアプリで例外を使用しています。

于 2012-02-02T05:19:33.870 に答える
0

ジェネリック基本クラスをサポートできない場合のもう 1 つの戦略は、拡張メソッドの実装です。

public static void ThisMethodShouldThrow(this Iinterface obj)
{
     if(obj.ConditionToThrowIsMet) throw new...
}

これには、継承チェーンを必要としないという利点があります。

于 2010-10-13T13:09:27.833 に答える
0

この情報を提供する最善の方法は、各インターフェイスに提供する XML ドキュメントにあると思います。そこで、ホストがそのエラーを処理できるように、メソッドによってスローされる例外を指定できます。

于 2010-10-13T11:54:03.887 に答える