我有一个函数,它在一个 using
块中返回:
int f() {
using (...) {
...
return someVar;
}
}
我刚刚注意到这个问题,并将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();
}
}
确实,编译器报错:
error CS0161: `MainClass.f()': not all code paths return a value
为什么在另一个情况下不会报错呢?
是因为我之前说的吗?如果无法初始化资源,我们将会崩溃,所以编译器认为这并不重要。
try-finally
的语句块,没有catch
。如果你在代码中删除了catch
,就不会出现编译错误。 - juharrusing
之外,即使从概念上讲,在该上下文之外它们永远没有意义。而且从概念上讲,您仍然面临与从using
内部返回相同的情况,即现在需要证明当using
运行时变量肯定已经被分配,这是一个与证明using
具有返回值使方法的终点不可达的问题相同的问题。 - Servytry/finally
的参考资料,但我可能没有仔细阅读。我看到了try/finally
,但由于很少见到不带catch
的try
,所以我可能让自己相信我实际上看到了try/catch
。我确实看到了使用try/finally
而不是using
的示例,但由于我从未使用过不带catch
的try/finally
语句,因此我盲目地期望如果try/catch/finally
导致编译错误,那么try/finally
也会导致编译错误。 - pushkin