我有一个函数在 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/