GOTO inside using block, will the object get dispo

2019-01-20 13:26发布

问题:

I'm quite unsure about using goto inside an using block.

For example:

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

    if(someCondition) goto myLabel;
}

Now if someCondition is true the code execution will move on to myLabel, but, will the the object get disposed?

I've seen some pretty good questions here on this topic but they all talk about different things.

回答1:

The using statement is essentially a try-finally block and a dispose pattern wrapped up in one simple statement.

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

Is equivalent to

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

Thus, any jump from the "try-block", be it throwing an exception, the use of goto (unclean!) &tc. will execute the Disposal of the object being used in that "finally" block..



回答2:

Yes.


But why not try it yourself?

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

Result:

Disposed
End



回答3:

let's try:

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");
        }
    }

}

Console output is : disposed after label

Dispose() execute before codes after the label .



回答4:

using(Stream s = new Stream("blah blah blah"))
{    
    if(someCondition) goto myLabel;
}

equals to

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

So, as soon as you leave the using block, the finally block does happen, no matter what made it quit.



标签: c# .net .net-4.0