2017-08-08 36 views
1

就像這個例子:分支理論上無法達到什麼樣的例外情況?

public MatchResult GetResult(int home, int away) 
{ 
    if (home == away) 
     return MatchResult.Draw; 
    else if (home > away) 
     return MatchResult.HomeWins; 
    else if (home < away) 
     return MatchResult.AwayWins; 

    throw new Exception("Should be impossible"); 
} 

我知道我可以用else上次語句解決這個問題,但我常常希望還是明確。舉例來說,這當然是一個簡化的情況。

下一頁到:就是編譯器會引發not all code paths return a value的原因,因爲情況是編譯器或因爲其他原因太複雜了(就像我們可以在理論上通過從非託管代碼更改home中途的值不同的線程或東西?)

+0

我不能看到編譯器如何生成錯誤從你的代碼中,因爲所有分支都有一個返回值或者至少有一個異常。然而,你的第一個問題是基於意見的,因此將被關閉。無論如何:一個參數怎麼可能不相等,更大或更小呢?你認爲如何才能達到這個例外? – HimBromBeere

+0

說到這種代碼分析工具(如ReSharper)可能會將您的異常代碼標記爲無法訪問,您應該將其刪除。 – HimBromBeere

+0

ReSharper也不會檢測到這一點,只是測試它。 –

回答

3

我知道我可以用最後一條語句的其他語句來解決這個問題,但我通常更喜歡明確。

如果不告訴編譯器,你可以保持顯式。由於明確唯一的理由是爲了幫助讀者,所以取代實際的if這個評論給了你兩全其美的方法:程序員看到了這個情況,而編譯器不會用不必要的throwreturn s來打擾你。

if (home == away) 
    return MatchResult.Draw; 
else if (home > away) 
    return MatchResult.HomeWins; 
else // if (home < away) 
    return MatchResult.AwayWins; 

在你真正需要拋出一個異常,因爲一些分支是不可能達到最好的行動當然是的情況下使用斷言:

if (!CheckNonNegative(arg)) { 
    throw new ArgumentException(nameof(arg)); 
} 
... 
if (arg == 0) { 
    ... // Do something 
} else { 
    Debug.Assert(arg > 0, "Method has checked arg to be non-negative"); 
    ... // Do something else 
} 
+0

當我們編譯器需要一個返回值時,最後一個例子不會拋出編譯錯誤嗎? –

+0

@DirkBoer如果您在詢問是否可以使用斷言來代替'throw',那麼答案是「否」,因爲斷言在釋放模式下是關閉的。 – dasblinkenlight

0

我會爭辯說(如果例外被拋出 - 我寧願更改代碼)這應該會拋出一個NotSupportedException。通常,如果調用某個方法時拋出異常,但此時該對象的當前狀態不支持方法調用。

這只是一個短暫的說法,如果邏輯規律崩潰了,您處於不受支持的狀態,無法完成該方法。

相關問題