簡體   English   中英

.NET編譯器和“並非所有代碼路徑返回值”

[英].NET compiler and “Not all code paths return a value”

為什么在如下代碼中.NET編譯器無法確定所有代碼路徑都返回值?

bool Test(bool param) {
    bool test = true;
    if (param)
        test = false;
    else
        test = false;
    if (!test)
        return false;
}

錯誤CS0161:並非所有代碼路徑都返回值!

代碼可以重構 - 但編譯器不建議這樣做。 然而,所有返回路徑都被覆蓋 - 那么為什么編譯器會抱怨它們不是?

編輯:我想這里的結論是:

(error CS0161) + (all code paths obviously return a value) => refactor code.  

一旦你養成了翻譯的習慣,我想一切都還可以。

來自Visual Studio 2010附帶的C#語言規范4.0。

10.6.10“方法體”:

當方法的返回類型不為void時,該方法主體中的每個return語句都必須指定一個可隱式轉換為返回類型的表達式。 必須無法訪問值返回方法的方法主體的端點。 換句話說,在值返回方法中,不允許控制流出方法體的末尾。

可達性的定義在這里(強調添加):

8.1“終點和可達性”:

如果可以通過執行來達到語句,則說該語句是可訪問的。 相反,如果不可能執行語句,則說該語句無法訪問。

...

要確定特定語句或端點是否可訪問,編譯器將根據為每個語句定義的可訪問性規則執行流分析。 流分析考慮了控制語句行為的常量表達式(第7.19節) 的值 ,但不考慮非常量表達式的可能值

因為!test不是常量表達式(即使它總是評估為true ),編譯器也不得在流分析中考慮它。 這種限制的一個原因(可能是唯一的原因)是在一般情況下進行這種流動分析是不可能的。

要消除錯誤,您需要在else子句中或在方法結束時無條件地使用另一個return語句。

來自Eric Lippert的博客

可達性分析儀不是很聰明。 它沒有意識到只有兩種可能的控制流程,並且我們已經用返回覆蓋了所有這些流程。

(博客文章是關於switch語句的,但我想可達性分析器對於if語句來說並不聰明。)

這僅僅代表了編譯器在初始化內容和執行哪些行方面的智能程度的局限性。

我不時遇到這種情況。 但它很少是一個問題。 我通常會稍微重構代碼。

讓我們向后分析代碼:

問題:代碼不返回任何值。

問題:在代碼中返回值的位置?

答:就在最后一行。

結論:所以代碼行(最后一行)應該總是返回一個值。

問題:最后一行總是返回一個值嗎?

答案:不,它只在testfalse時返回值,而在第一行設置為true

結論:正如編譯器所說,這個函數永遠不會返回一個值,而它應該返回bool

讓我直接回答你的問題,而不是詳細說明。

  1. 返回類型的函數被指定為Bool,因此該函數必須返回True或false
  2. Param已被定義為輸入參數,因此無法在編譯時確定其值
  3. 測試變量的值取決於參數,並且根據步驟2,在編譯時無法確定參數值,因此在編譯時無法確定測試
  4. 由於test的值不稱為編譯時間(按照步驟3),因此它開始為if(!test)尋找else / default root,因此它會拋出錯誤。

謝謝

暫無
暫無

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

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