代码之家  ›  专栏  ›  技术社区  ›  tafa

在使用块的中间返回

  •  166
  • tafa  · 技术社区  · 16 年前

    比如:

    using (IDisposable disposable = GetSomeDisposable())
    {
        //.....
        //......
        return Stg();
    }
    

    我认为这不是一个合适的地方,为回报声明,是吗?

    7 回复  |  直到 16 年前
        1
  •  205
  •   JaredPar    16 年前

    唯一会导致您出现问题的是如果在使用语句的中间返回,并另外返回IN使用变量。但同样,这也会导致问题,即使您没有返回,只是保留了对变量的引用。

    using ( var x = new Something() ) { 
      // not a good idea
      return x;
    }
    

    Something y;
    using ( var x = new Something() ) {
      y = x;
    }
    
        2
  •  160
  •   James Curran    16 年前

    很好。

    你显然是这么想的

    using (IDisposable disposable = GetSomeDisposable())
    {
        //.....
        //......
        return Stg();
    }
    

    IDisposable disposable = GetSomeDisposable()
    //.....
    //......
    return Stg();
    disposable.Dispose();
    

    不可否认,这将是一个问题,并将使 using 声明毫无意义,这就是为什么 它的作用。

    编译器确保在控件离开块之前释放对象——不管它如何离开块。

        3
  •  98
  •   Jon Skeet    16 年前

    绝对没问题,一点问题也没有。你为什么认为这是错误的?

    using语句只是try/finally块的语法糖,正如Grzenio所说,从try块返回也可以。

    将对返回表达式求值,然后执行finally块,然后该方法将返回。

        4
  •  28
  •   Grzenio    16 年前

    这将完美地工作,就像回到中间。 try{}finally{}

        5
  •  19
  •   mbillard    16 年前

    这是完全可以接受的。A. 使用 语句确保无论发生什么情况,IDisposable对象都将被释放。

    从…起 MSDN :

    using语句确保即使在调用对象上的方法时发生异常,也会调用Dispose。通过将对象放在try块中,然后在finally块中调用Dispose,可以获得相同的结果;事实上,编译器就是这样翻译using语句的。

        6
  •  16
  •   Bertrand    7 年前

    using 正在工作:

    private class TestClass : IDisposable
    {
       private readonly string id;
    
       public TestClass(string id)
       {
          Console.WriteLine("'{0}' is created.", id);
          this.id = id;
       }
    
       public void Dispose()
       {
          Console.WriteLine("'{0}' is disposed.", id);
       }
    
       public override string ToString()
       {
          return id;
       }
    }
    
    private static TestClass TestUsingClose()
    {
       using (var t1 = new TestClass("t1"))
       {
          using (var t2 = new TestClass("t2"))
          {
             using (var t3 = new TestClass("t3"))
             {
                return new TestClass(String.Format("Created from {0}, {1}, {2}", t1, t2, t3));
             }
          }
       }
    }
    
    [TestMethod]
    public void Test()
    {
       Assert.AreEqual("Created from t1, t2, t3", TestUsingClose().ToString());
    }
    

    输出:

    “t1”已创建。
    “t2”已创建。
    “t3”已创建。
    “从t1、t2、t3创建”已创建。
    处理“t3”。
    处理“t2”。
    处理“t1”。

    在return语句之后但在函数退出之前调用disposed。

        7
  •  -4
  •   Bugs Manjeet    7 年前

    也许这不是100%的事实,这是可以接受的。。。

    以此为例:

    using (var memoryStream = new MemoryStream())
    {
        using (var textwriter = new StreamWriter(memoryStream))
        {
            using (var csv = new CsvWriter(textwriter))
            {
                //..write some stuff to the stream using the CsvWriter
                return memoryStream.ToArray();
            }
        }
    }
    

    正确的方法是确保正确处理所有以前的使用:

    using (var memoryStream = new MemoryStream())
    {
        using (var textwriter = new StreamWriter(memoryStream))
        {
            using (var csv = new CsvWriter(textwriter))
            {
                //..write some stuff to the stream using the CsvWriter
            }
        }
    
        return memoryStream.ToArray();
    }