簡體   English   中英

當並非所有代碼路徑都返回時,C#編譯器不會抱怨

[英]C# compiler doesn't complain when not all code paths return

我有一個在using塊中返回的函數:

int f() {
  using (...) {
     ...
     return someVar;
  }
}

我剛注意到這一點,並將using塊之外的return移動到最外層的函數范圍,因為我覺得這就是return的位置。

但我很困惑為什么編譯器沒抱怨並非所有代碼路徑都返回。 這只是因為如果它無法初始化資源,我們會崩潰,所以沒關系?

舉個例子:

class MainClass {
  public static void Main (string[] args) {
    f();
  }

  public static int f() {
    using(A a = new A()) {
      return 1;
    }
  }
}

class A : IDisposable{
  public void Dispose() { }
}

編譯器並不關心我們只返回using 但是,我認為using語句基本上是try/catch語法糖

如果我們更換

using(A a = new A()) {
  return 1;
}

A a = new A();;
try  {
  return 1;
}

catch (Exception e) { }
finally {
  if (a != null) {
    ((IDisposable) a).Dispose();
  }
}

確實,編譯器抱怨:

錯誤CS0161:`MainClass.f()':並非所有代碼路徑都返回一個值

為什么不在其他情況下抱怨?

這只是我上面所說的嗎? 如果它無法初始化資源,我們會崩潰,因此編譯器決定它無關緊要。

實際上:

using(var objectName = <init-expression>) {
    //...
}

或多或少相當於:

objectName = <init-expression>;
try {
    //...
} finally {
    objectName.Dispose();
}

所以這是一個try - finally -block:如果在執行過程中出現問題,異常將被拋出該方法(主要是在finally部分完成之后)。

try - 但finally不會創建替代代碼路徑:如果try -part返回某些內容或拋出錯誤,它將首先執行finally -part,但隨后拋出異常或返回應該返回的內容。

基本上,是的。 using語句會將它的異常拋出堆棧。 捕獲異常並使用不返回的finally塊意味着該方法既不拋出異常也不返回。

編譯器也不會抱怨以下方法

public int SuperCool(){
   throw new NotImplementedException("bummer");
}

為了擴展一點,因為我錯過了一個編輯,其中catch塊最初不存在:

catch塊“吃掉”異常,導致它不再向上移動堆棧,編譯器注意到沒有返回值或異常的路徑。

暫無
暫無

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

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