[英]How to specify exceptions to be thrown by an implementor of an interface?
我目前正在開發一個解決方案,並以一種強有力地實現策略/提供者模式的方式進行設計。 因此,該解決方案公開了許多接口並包含這些接口的默認實現,這些接口可以通過DI類型方法替換。
在主機應用程序使用多個這些接口的情況下,它期望處理可能發生的某些異常,例如IDataRetriever
接口具有方法SomeDataType GetData(int timeout);
並且主機可以處理一些自定義異常,例如DataRetrievalTimeoutException
或NetworkConnectionException
。
我的問題是,標記接口類的最佳方法是什么,當開發人員實現它時,他們會知道應該拋出某些異常並由主機處理?
目前我剛剛將xml標簽添加到方法xml注釋中 - 這是否足夠?
你不能在一個界面。 你可以在基類。
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.