当并非所有代码路径都返回时,C# 编译器不会提示

标签 c# compiler-errors using

我有一个函数在 using block 中返回:

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

我刚刚注意到这一点,并将 return 移到了 using block 之外,移到了最外层的函数范围,因为我觉得那是 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();
  }
}

确实编译器提示:

error CS0161: `MainClass.f()': not all code paths return a value

为什么在另一种情况下它不提示?

仅仅是我上面说的吗? 如果它无法初始化资源,我们就会崩溃,因此编译器认为这无关紧要。

最佳答案

实际上是:

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

或多或少等同于:

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

所以它是一个try - finally -block:如果在执行过程中出现问题,异常将被抛出方法(主要是在 finally 部分完成之后)。

A try - finally但是不会创建替代代码路径:如果 try -part 返回一些东西或抛出错误,它将首先执行 finally -部分,但随后要么抛出异常,要么返回应该返回的内容。

关于当并非所有代码路径都返回时,C# 编译器不会提示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41639325/

相关文章:

c# - 当主可执行文件使用旧的 log4net 版本时,在 dll 中使用 LinqToExcel

c# - Math.Acos 不工作?

c++ - C++中的“' yc ' can not be used as a function”错误

syntax - Ocaml语法与 bool 值匹配

c++ - bad_alloc 标识符无法识别?

c# - 在 C# 中使用 using 并在 using 中获取变量赋值

c# - 何时首选 lambda 表达式中的参数?

c# - 在 C# 中用 Regex 替换两个或多个空格

c# - 为什么我们在 c# 中将 using 放在 streamreader 之前

c++ - 为什么 `using A::f` 没有按预期工作?