在using语句中处理隐式引用

sam*_*mis -1 c#

当"嵌套" using语句/块时,例如a StreamWriterFileStream

using (FileStream fs = File.Open(path, FileMode.Create))
{
    using (var fsw = new StreamWriter(fs))
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

FileStream如果它的引用是隐含的,那么它会被妥善处理吗?如果没有,在FileStream处理时会丢弃它吗?

    using (var fsw = new StreamWriter(File.Open(path, FileMode.Create)) )
    {
        ...
    }
Run Code Online (Sandbox Code Playgroud)

此外,以下"堆叠" using语句的生成方式是否与第一个"嵌套"示例不同(嵌套的try/catch块是否依赖于语法)?

using (FileStream fs = File.Open(path, FileMode.Create))    
using (var fsw = new StreamWriter(fs))
{
    ...
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*ert 5

如果FileStream的引用是隐式的,它会被正确处理掉吗?当FileStream本身被丢弃时,它会被处理掉吗?

这个问题是荒谬的.我相信你打算问的问题是:

如果StreamWriter(或读取器)处置(或关闭),它会自动处理底层Stream

是.为了将来参考,请考虑阅读文档; 你的问题在那里得到了明确的答

现在,您可能会如下推理:假设在创建流之后但在创建编写器或读取器之前抛出线程中止异常.在两用情况下,流被处理; 在一次使用的情况下,它不是.因此,两用案例既不同又更好.

这种推理似是而非.假设在分配了流的句柄之后但在分配了文件流变量之前抛出了线程中止异常; 即使在两用情况下,也不会处理流.

故事的寓意是:using在线程中止异常的世界中,你不能依赖于处理关键资源.using是为了礼貌; 它不能保证资源将被释放.

以下"堆叠"使用语句生成的方式与第一个"嵌套"示例不同吗?

请每个问题只询问一个问题.

问题不明确.您的问题是这两种形式在语义上是否完全相同,或者它们是否产生完全相同的IL?那些问题有相反的答案.是的,它们在语义上是等价的,不,如果关闭优化,它们不一定产生相同的IL.

一般来说,

statement
Run Code Online (Sandbox Code Playgroud)

{
  statement
}
Run Code Online (Sandbox Code Playgroud)

在语义上是等价的.(虽然请注意,声明语句在语句块不是的某些语境中在语法上是非法的.当然,大括号引入了一个声明空间.)

但是,C#编译器可能会选择生成额外的nop指令,以便调试器有一些地方可以将断点与大括号相关联.因此,生成的代码不相同.例如,生成额外的nop会对分支位置产生连锁效应,从而导致分支偏移大小,从而导致分支指令大小,从而导致分支指令操作码.

  • @samusarin:如果你走这条路,你会发现你正在重新发明约束执行区域,这是一种几乎没有人理解的CLR功能.拥有一个不可中断的代码区域是否可行?**是**.事前你从未听说过这个功能,这表明有人真正需要解决这个问题是多么罕见,以及解决这个问题的难度.**简单地构建程序更容易,因此不需要及时调用处理器.** (2认同)