【问题标题】:GOTO inside using block, will the object get disposed?GOTO 在 using 块中,对象会被处理吗?
【发布时间】:2012-09-25 13:43:14
【问题描述】:

我不太确定在 using 块内使用 goto

例如:

using(stream s = new stream("blah blah blah"));
{
    //do some stuff here

    if(someCondition) goto myLabel;
}

现在如果someCondition 为真,代码执行将继续到myLabel,但是,对象会被释放吗?

我在这里看到了一些关于这个主题的很好的问题,但他们都在谈论不同的事情。

【问题讨论】:

  • 为什么不自己检查一下?
  • 你确定你使用goto吗? ;-)
  • I'm quite unsure about using goto inside an using block. - 我不太确定在一般情况下是否使用goto,而不仅仅是在using 块内。
  • 我很惊讶 C# 的创建者有胆量构建高级复杂的编程语言,然后混入 goto。你不是在汇编中编程,你知道的。
  • goto has its advantages. :) - @SeanVaughn,真的吗?我已经编写 C# 代码 9 年了,但仍然没有看到任何优势。

标签: c# .net .net-4.0


【解决方案1】:

是的。


但是为什么不自己试试呢?

void Main()
{
    using(new Test())
    {
        goto myLabel;
    }
myLabel:
    "End".Dump();
}
class Test:IDisposable
{
    public void Dispose()
    {
        "Disposed".Dump();
    }
}

结果:

弃置
结束

【讨论】:

    【解决方案2】:

    using 语句本质上是一个 try-finally 块和一个封装在一个简单语句中的 dispose 模式。

    using (Font font1 = new Font("Arial", 10.0f))
    {
        //your code
    }
    

    相当于

    Font font1 = new Font("Arial", 10.0f);
    try
    {
         //your code
    }
    finally
    {
         //Font gets disposed here
    }
    

    因此,任何从“try-block”跳转,无论是抛出异常,还是使用 goto (unclean!) &tc。将执行该“finally”块中正在使用的对象的 Disposal..

    【讨论】:

    • 因为每个答案都有相同的意义,所以只选择一个是无关紧要的。但是,因为你的代表很低。 :)
    【解决方案3】:

    我们试试吧:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication2
    {
        class Program
        {
            static void Main(string[] args)
            {
                int i = 0;
                using (var obj = new TestObj())
                {
                    if (i == 0) goto Label;
                }
                Console.WriteLine("some code here");
    
            Label:
                Console.WriteLine("after label");
    
            Console.Read();
            }
        }
    
        class TestObj : IDisposable
        {
            public void Dispose()
            {
                Console.WriteLine("disposed");
            }
        }
    
    }
    

    控制台输出是: 处置 标签后

    Dispose() 在标签之后的代码之前执行。

    【讨论】:

      【解决方案4】:
      using(Stream s = new Stream("blah blah blah"))
      {    
          if(someCondition) goto myLabel;
      }
      

      等于

      Stream s;
      try
      {
           s = new Stream("blah blah blah");
           if(someCondition) goto myLabel;
      }
      finally
      {
        if (s != null)
          ((IDisposable)s).Dispose();
      }
      

      所以,一旦您离开 using 块,finally 块就会发生,不管是什么让它退出。

      【讨论】:

        猜你喜欢
        • 2012-09-18
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-10
        • 1970-01-01
        相关资源
        最近更新 更多