Answers:
正如其他几个人指出的那样,这不是问题。
唯一会引起问题的情况是,如果您在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
工作:
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语句之后但函数退出之前调用已处置的对象。
也许这不是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();
}