【问题标题】:C# 'using' statement translated by the compiler into 'try finally'C# \'using\' 语句被编译器翻译成 \'try finally\'
【发布时间】:2022-11-30 02:45:36
【问题描述】:

根据MSDNthis accepted answer

using (T resource = expression)
    embedded-statement

被编译器翻译成如下代码:

{
    T resource = expression;//Shouldn't this statement be moved inside the try block?
    try
    {
        embedded-statement
    }
    finally
    {
        if (resource != null)
             ((IDisposable)resource).Dispose();
    }
}

我的问题是:为什么在 try 块周围有一个额外的 {}?不应该将第一条语句移到 try 块内吗?

MSDN 解释说:

前面的代码示例在编译时扩展为以下代码(注意额外的花括号为对象创建了有限的范围):

但根据另一个MSDN页面,

通过使用 finally 块,您可以清理任何资源 分配的在 try 块中

【问题讨论】:

    标签: c#


    【解决方案1】:

    如果资源是在 try 块中声明的,它在 finally 块中是不可见的,因为变量的范围总是限于实际块(并且块嵌套得更深)。

    周围的块将资源的范围限制为此 try-finally。

    try-finally (C# Reference) 的文档说:

    通过使用 finally 块,您可以清除在 try 块中分配的所有资源,并且即使在 try 块中发生异常也可以运行代码。通常,finally 块的语句在控制离开 try 语句时运行。控制权的转移可能是由于正常执行、执行 break、continue、goto 或 return 语句,或者从 try 语句传播异常而发生的。

    【讨论】:

    • 但是如果在T resource = expression;(var reader = new StringReader(manyLines);) from MSDN example的过程中抛出异常,finally块还会被执行吗?
    • 不,这是设计使然。如果在初始化时抛出异常,则没有什么可处理的,因为没有为变量赋值。
    • finally 块的目的是始终进行评估。即使发生异常或当 try-block 留下returnbreakcontinuegoto时。 try-finally (C# Reference) 的文档说:“通过使用 finally 块,您可以清理在 try 块中分配的任何资源,即使在 try 块中发生异常,您也可以运行代码。”
    • 如果变量可见性是原因,那么我们可以先声明变量并将其分配给null,然后在 try 块中对其进行初始化?这比原始代码好吗?
    猜你喜欢
    • 1970-01-01
    • 2014-09-30
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 1970-01-01
    • 2011-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多