簡體   English   中英

如何指定接口的實現者拋出的異常?

[英]How to specify exceptions to be thrown by an implementor of an interface?

我目前正在開發一個解決方案,並以一種強有力地實現策略/提供者模式的方式進行設計。 因此,該解決方案公開了許多接口並包含這些接口的默認實現,這些接口可以通過DI類型方法替換。

在主機應用程序使用多個這些接口的情況下,它期望處理可能發生的某些異常,例如IDataRetriever接口具有方法SomeDataType GetData(int timeout); 並且主機可以處理一些自定義異常,例如DataRetrievalTimeoutExceptionNetworkConnectionException

我的問題是,標記接口類的最佳方法是什么,當開發人員實現它時,他們會知道應該拋出某些異常並由主機處理?

目前我剛剛將xml標簽添加到方法xml注釋中 - 這是否足夠?

XML標簽(以及您想要編寫的任何其他文檔)基本上是您目前在“vanilla”.NET中最接近的。

您可能希望查看代碼約定 ,它允許您使用合同注釋您的接口,其中包括異常,前置條件等。

你不能在一個界面。 你可以在基類。

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);
}

我建議在接口中定義異常類,並指定除非CPU處於激烈狀態或存在其他如此劇烈的情況,否則不應允許任何不從那些派生的異常轉義(盡管如此,它可能不是一個壞主意有一個顯式定義的IWoozle.SystemCorruptionException這樣如果一個Pokemon處理程序只是捕獲,記錄並拋出異常,日志將反映出至少有人認為異常是重要的)。

我認為Microsoft的建議是避免定義自定義異常類型是不幸的,因為這意味着沒有干凈的方法來區分IEnumerator<T>.MoveNext()拋出InvalidOperationException因為枚舉期間底層集合被更改,或者是否內部處理IEnumerator<T>.MoveNext()遇到InvalidOperationException ,只是讓它冒泡到調用者。 相反, IEnumerator<T>.MoveNext()在前一種情況下拋出了IEnumerator.InvalidatedEnumeratorException ,然后任何轉義的InvalidOperationException都必須代表后一種情況。

這不應該由任何類實現接口嗎?

例如,如果我使用您的接口並使用GetData方法實現我自己的類,我可以從任何地方“獲取”數據。 假設它是一個Web服務,那么可以拋出的異常類型可能與我從本地文件系統“獲取”數據時的異常類型不同。

因此,在我的實現中,我將實現(並記錄)特定於implmentation的那些異常,以便使用該實現的任何代碼都可以處理它們。 如何處理這些異常可能對實現非常具體,比如我在Web應用程序中使用它們而不是桌面應用程序。

我認為提供此信息的最佳方法是在為每個接口提供的XML文檔中。 在那里,您可以指定方法拋出的異常,以便主機可以處理該錯誤。

如果您不能支持通用基類,另一種策略是擴展方法實現。

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

這樣做的好處是不需要繼承鏈。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM