代码之家  ›  专栏  ›  技术社区  ›  Andy White

.NET-用单个using语句替换嵌套using语句

  •  6
  • Andy White  · 技术社区  · 15 年前

    如果遇到这样的C代码,其中包含嵌套的using语句/资源:

    using (var response = (HttpWebResponse)request.GetResponse())
    {
        using (var responseStream = response.GetResponseStream())
        {
            using (var reader = new BinaryReader(responseStream))
            {
                // do something with reader
            }
        }
    }
    

    换成这样安全吗?

    using (var reader = new BinaryReader(((HttpWebResponse)request.GetResponse()).GetResponseStream()))
    {
        // do something with reader
    }
    

    5 回复  |  直到 15 年前
        1
  •  12
  •   Reed Copsey    15 年前

    你需要单独的using语句。

    BinaryReader 将被释放,而不是用于构造它的对象。

    为了找出原因,看看 using statement 实际上是的。它需要您的第二个代码,并执行相当于:

    {
        var reader = new BinaryReader(((HttpWebResponse)request.GetResponse()).GetResponseStream());
        try
        {
          // do something with reader
        }
        finally
        {
            if (reader != null)
                ((IDisposable)reader).Dispose();
        }
    }
    

    Dispose() 拜访 Response ResponseStream .

        2
  •  13
  •   Ken Richards    15 年前

    你应该把你的using语句堆叠起来-它有你想要的效果:

    using (var response = (HttpWebResponse)request.GetResponse())
    using (var responseStream = response.GetResponseStream())
    using (var reader = new BinaryReader(responseStream))
    {
        // do something with reader
    }
    
        3
  •  3
  •   Curt Nichols    15 年前

    FWIW,这里有另一种方法来拼写您的原始示例,它可以满足任何关于嵌套的沮丧:

    using (var response = (HttpWebResponse)request.GetResponse())
    using (var responseStream = response.GetResponseStream())
    using (var reader = new BinaryReader(responseStream))
    {
        // do something with reader
    }
    

    读卡器是否处理流实际上是读卡器的功能,而不是“使用”。正如我所记得的,读者的行为通常是这样的——他们拥有流的所有权,并在读者自身关闭时处理流。但我上面提供的表格应该没问题。

        4
  •  2
  •   Jim Mischel    15 年前

    BinaryReader.Close 将关闭基础流。 http://msdn.microsoft.com/en-us/library/system.io.binaryreader.close.aspx

    另外,根据 HttpWebResponse ,则必须关闭基础流或释放响应。 http://msdn.microsoft.com/en-us/library/system.net.httpwebresponse.aspx

    因此,您提供的第二个示例将起作用。

        5
  •  0
  •   hcp    12 年前

    using (IType1 a = new Type1(), b = new Type1()){}

    但是,这意味着您的对象必须是同一类型的。你可以这样称呼他们

    using (IDisposable a = new Type1(), b = new Type2()){}

    但是,当然,您只能访问IDisposable方法,而不投射对象,这有点愚蠢。所以,我相信你可以用

    using (var a = new Type1(), b = new Type2()){}

    这似乎为您提供了正确类型的对象引用,允许您访问已分配类型的正确方法,并处理创建的两个对象。如果有人知道我为什么不对,请告诉我,因为这似乎对我有用?(我知道这个问题真是个老问题,但这是我自己在寻找答案时能找到的全部)