我有一个在using
块中返回的函数:
int f() { using (...) { ... return someVar; } }
我刚注意到这一点,并将块的return
外部移动using
到最外层的功能范围,因为我觉得这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 =) { //... }
或多或少相当于:
objectName =; try { //... } finally { objectName.Dispose(); }
所以这是一个try
- finally
-阻塞:如果在执行过程中出现错误,异常会被抛出的方法(主要是后finally
部分已经完成).
A try
- finally
但是不会创建替代代码路径:如果try
-part返回某些内容或抛出错误,它将首先执行finally
-part,然后抛出异常或返回应该返回的内容.