亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

為什么編譯器沒有檢測到這里會拋出異常?

為什么編譯器沒有檢測到這里會拋出異常?

C#
陪伴而非守候 2023-08-13 16:03:37
我試圖將異常拋出邏輯包裝到另一個類中,以便更容易拋出自定義異常。每個類都將使用對此 Thrower 類的直接引用或接口,無論哪種最合適。我編寫了一個簡單的類來處理它并且它在大多數情況下都可以工作,但是我在具有返回類型的方法中遇到了一種情況,即使總是拋出異常,編譯器也無法檢測到它并抱怨并非所有路徑返回一個值。以下代碼顯示了 Thrower 類和任何使用所述 Thrower 的類的結構的簡化形式。public class Thrower{    public void ThrowException()    {        throw new Exception("Im an exception");    }}public class Foo{    // Does not work, compiler complains about not all paths returning values.    public int ExceptionNotDetected(bool shouldThrow)    {        if (!shouldThrow)        {            return 1;        }        var thrower = new Thrower();        thrower.ThrowException();    }    // Works fine.    public int ExceptionDetected(bool shouldThrow)    {        if (!shouldThrow)        {            return 1;        }        throw new Exception("Im an exception");    }}據我所知,使用 Thrower 的方法必須返回一個值或拋出異常。由此看來,ExceptionNotDetected 和 ExceptionDetected 方法在功能上是等效的。那么為什么編譯器會抱怨 ExceptionNotDetected 呢?編輯:關于設計,這純粹是為了說明目的,因為我真正想做的就是了解發生了什么。如果我沒有在帖子描述中正確澄清這一點,我深表歉意。話雖這么說,我很欣賞有關結構的建議。
查看完整描述

3 回答

?
慕容森

TA貢獻1853條經驗 獲得超18個贊

編譯器只能看到當前方法的返回類型,“ThrowExeption()”方法什么也不返回(void)。

它不會檢查被調用方法的內部以查看是否會返回異常。


查看完整回答
反對 回復 2023-08-13
?
一只萌萌小番薯

TA貢獻1795條經驗 獲得超7個贊

由于 C# 不像 Java 那樣具有檢查異常,因此編譯器無法知道拋出者實際上拋出了異常。


但你可以顛倒邏輯


 if (shouldThrow)

    {

    var thrower = new Thrower();

    thrower.ThrowException();

    }

    return 1;

這樣,編譯器將假設返回 1,并且 ThrowException 方法是一個常規 void,它像任何其他 void 方法一樣可能會拋出異常。


查看完整回答
反對 回復 2023-08-13
?
搖曳的薔薇

TA貢獻1793條經驗 獲得超6個贊

很簡單,因為編譯器不會分析函數內部的代碼來檢測該函數是否總是拋出異常。

C# 似乎沒有“永不返回”的屬性。

而且,沒有理由這樣編寫代碼:

  1. 如果異常類型非常具體,您應該使用不同的異常類型。因此,您將通過調用來拋出它throw new MyExceptionType(my_parameters);。

  2. 如果創建稍微復雜一些,那么您可以向類中添加一個靜態方法來創建異常對象:throw new MyExceptionType::CreateFromThatData(…);

  3. 如果僅從單個類引發異常,則該類中可能有一個靜態函數來創建適當的異常對象。這樣,您可以根據某些條件返回不同的異常類型。所有 C# 異常都源自Exception.

  4. 如果您確實想要一個異常工廠,那么static class使用一些(靜態)方法來創建所需的異常可能會起作用。

  5. 在您的代碼中,我確實沒有看到創建對象thrower然后調用它的方法來引發異常的意義。您知道需要 2 行代碼來引發異常,而不是一行。

  6. 將調用隱藏throw在函數內會使代碼更難以理解和驗證。thrower.ThrowException確實拋出異常以及是哪一個異常。

  7. 正如其他答案所示,您可以首先放置引發異常的方法調用,這樣編譯器就不會報告某些部分不返回值。

您的設計和代碼過于復雜,因此產生的問題比解決的問題還要多。


查看完整回答
反對 回復 2023-08-13
  • 3 回答
  • 0 關注
  • 162 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號