【发布时间】:2010-10-14 08:22:30
【问题描述】:
类似:
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
我认为这里不适合做退货声明,是吗?
【问题讨论】:
标签: c# dispose idisposable using-statement
类似:
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
我认为这里不适合做退货声明,是吗?
【问题讨论】:
标签: c# dispose idisposable using-statement
正如其他几个人指出的那样,这通常不是问题。
唯一会导致问题的情况是,如果您在 using 语句的中间返回并另外返回 in using 变量。但是话又说回来,即使您没有返回并且只是保留对变量的引用,这也会给您带来问题。
using ( var x = new Something() ) {
// not a good idea
return x;
}
同样糟糕
Something y;
using ( var x = new Something() ) {
y = x;
}
【讨论】:
return 语句使任何代码路径都无法访问using 块的末尾。 using 块的末尾需要运行,以便可以在需要时释放对象。
完全没问题。
你显然是这么想的
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
被一味翻译成:
IDisposable disposable = GetSomeDisposable()
//.....
//......
return Stg();
disposable.Dispose();
诚然,这将是一个问题,并且会使 using 声明变得毫无意义 --- 这就是它不是的原因。
编译器确保对象在控制离开块之前被释放——不管它是如何离开块的。
【讨论】:
完全没问题 - 完全没有问题。为什么你认为这是错误的?
using 语句只是 try/finally 块的语法糖,正如 Grzenio 所说,从 try 块中返回也可以。
将计算返回表达式,然后执行 finally 块,然后方法将返回。
【讨论】:
这将完全正常,就像在try{}finally{}中间返回一样
【讨论】:
这是完全可以接受的。 using 语句确保 IDisposable 对象无论如何都会被释放。
来自MSDN:
using 语句可确保调用 Dispose,即使在您调用对象上的方法时发生异常也是如此。您可以通过将对象放在 try 块中,然后在 finally 块中调用 Dispose 来获得相同的结果;事实上,编译器就是这样翻译 using 语句的。
【讨论】:
下面的代码显示了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' 已被释放。
disposed 在 return 语句之后,函数退出之前调用。
【讨论】:
也许这不是 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();
}
}
}
我传入了一个要输出为 csv 的 DataTable。在中间返回时,它将所有行写入流,但输出的 csv 总是缺少一行(或多行,取决于缓冲区的大小)。这告诉我某些东西没有正确关闭。
正确的方法是确保所有以前的使用都正确处理:
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();
}
【讨论】: