返回在使用块的中间

就像是:

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

我相信这不是一个适当的回归声明的地方,是吗?

正如其他几个人一般指出,这不是一个问题。

唯一的情况会导致你的问题是,如果你在使用语句的中间返回,并另外返回使用variables。 但是,再次,这也会导致你的问题,即使你没有返回,只是保持一个variables的引用。

 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陈述变得毫无意义 – 这就是为什么这不是它所做的。

编译器确保对象在控制离开块之前被放置 – 无论它如何离开块。

这绝对没问题 – 没有任何问题。 你为什么认为这是错的?

using语句只是一个try / finally块的语法糖,Grzenio也认为从try块返回也是可以的。

返回expression式将被评估,然后finally块将被执行,然后方法将返回。

这会很好的工作,就像try{}finally{}中间返回一样。 try{}finally{}

这是完全可以接受的。 using语句确保IDisposable对象将被丢弃。

来自MSDN :

using语句确保即使在对象上调用方法时发生exception,也会调用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'被创build。
't2'被创build。
't3'被创build。
创build从t1,t2,t3创build。
't3'被处置。
't2'被处置。
't1'被处置。

在返回语句之后但在函数退出之前调用已处置的对象。

也许这不是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(); } } } 

我传入一个DataTable作为CSV输出。 在中间返回时,它将所有的行写入到stream中,但输出的csv总是缺less一行(或多个,取决于缓冲区的大小)。 这告诉我有些东西没有被正确closures。

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

 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(); } 

我不确定问题出在哪里,可能是在处理CsvWriter,或者它可能是一个C#系统的东西? 想法?