GOTO inside using block, will the object get disposed?

后端 未结 4 1679
我寻月下人不归
我寻月下人不归 2020-12-11 23:24

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

For example:

using(stream s = new stream(\"blah blah blah\"));
{
         


        
相关标签:
4条回答
  • 2020-12-11 23:36
    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.

    0 讨论(0)
  • 2020-12-11 23:37

    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..

    0 讨论(0)
  • 2020-12-11 23:42

    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

    0 讨论(0)
  • 2020-12-11 23:57

    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 .

    0 讨论(0)
提交回复
热议问题