类似于:
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
我认为在这里使用return语句不太合适,对吗?
类似于:
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
我认为在这里使用return语句不太合适,对吗?
正如其他人普遍指出的那样,在一般情况下,这不是一个问题。
唯一会导致问题的情况是,如果您在 using 语句中间返回并且同时返回 using 变量。但是,即使您不返回并仅保留变量的引用,这也会导致问题。
using ( var x = new Something() ) {
// not a good idea
return x;
}
同样糟糕
Something y;
using ( var x = new Something() ) {
y = x;
}
没问题。
你似乎在想
using (IDisposable disposable = GetSomeDisposable())
{
//.....
//......
return Stg();
}
被盲目翻译成:
IDisposable disposable = GetSomeDisposable()
//.....
//......
return Stg();
disposable.Dispose();
不可否认,这会是一个问题,并且会使 using
语句变得毫无意义 --- 这就是为什么它不会这样做的原因。
编译器确保在控制离开块之前清除对象 - 无论控制如何离开块。
IDisposable
对象,那就是传入一个Func
。例如,我有一些辅助方法用于创建连接和执行查询,但是我可以传入一个Func<IDataReader, T>
来提取结果。我的代码只需要一个using
块,而我的其他函数则专注于设置查询和参数。 - Adam完全没问题,为什么您认为它有错呢?
using语句只是try/finally块的语法糖,正如Grzenio所说,从try块中返回也是可以的。
return表达式将被评估,然后执行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 创建 'Created from t1, t2, t3'。
't3' 已销毁。
't2' 已销毁。
't1' 已销毁。
已释放的内容在返回语句之后但在函数退出之前被调用。
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();
}
return
语句使得using
块的结尾对于任何代码路径都不可访问。需要运行using
块的结尾以便在需要时处理对象的释放。 - mekb