C# using 语句
我真的很想把这件事从我的脑海里赶出去。请看下面的代码:
using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) {
List<string> resultsList = new List<string>();
foreach (DataRow dataRow in resultTable.Rows) {
resultsList.Add(dataRow[0].ToString());
}
return resultsList;
}
数据表是否已处理?有人可以解释一下这是如何转换为 try/catch/finally 块的吗? MSDN 指出,如果发生异常,Dispose 方法仍然会被调用,但是 return 语句呢?
或者我应该使用下面的代码:
List<string> resultsList = new List<string>();
using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) {
foreach (DataRow dataRow in resultTable.Rows) {
resultsList.Add(dataRow[0].ToString());
}
}
return resultsList;
也许应该使用第二个代码,但我只需要启发:)。请解释一下。谢谢。
I really want to get this out of my head. Please see below code:
using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) {
List<string> resultsList = new List<string>();
foreach (DataRow dataRow in resultTable.Rows) {
resultsList.Add(dataRow[0].ToString());
}
return resultsList;
}
Is the datatable disposed? Can someone explain how this is translated to a try/catch/finally block? MSDN states that if an exception occurred, the Dispose method will still be called but what about the return statement?
Or should i just use below code:
List<string> resultsList = new List<string>();
using (DataTable resultTable = DBUtility.GetSingleDBTableResult(connectionString, "SELECT * FROM MyDBTable")) {
foreach (DataRow dataRow in resultTable.Rows) {
resultsList.Add(dataRow[0].ToString());
}
}
return resultsList;
Probably, the second one should be used but I just need enlightenment :). Please explain. Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Using
不会捕获异常,它只是保证.Dispose()
调用。这是因为,
using (ResourceType resource = new ResourceType())
相当于:.Dispose()
调用将始终被评估。如果您在using
块内返回(在“真正”返回之前),则甚至会评估Dispose
调用。如果抛出异常,Dispose
调用甚至也会被评估。但是,如果引发异常,该异常仍会阻止后续代码行的求值(
.Dispose()
除外,它始终会求值)。因此,如果发生异常,您的
return
将不会在任何一个语句中返回,但您的DataTable
仍将被释放。如果你想保证即使发生错误也能返回,你需要这样做:
Using
does not catch exceptions, it just guarantees the.Dispose()
call.This is because,
using (ResourceType resource = new ResourceType())
is equivalent to:The
.Dispose()
call will always be evaluated. TheDispose
call is even evaluated if you return within yourusing
block (before it "really" returns). TheDispose
call is even evaluated if an exception is thrown.However, if an exception is thrown, that exception will still prevent subsequent lines of code from being evaluated (with the exception of the
.Dispose()
which is always evaluated).As such, if an exception occurs, your
return
will not return in either of your statements, but yourDataTable
will still be disposed.If you want to guarantee a return occurs, even when an error occurs, you want to do something like this:
在这两种情况下,DataTable 都会被释放(调用
.Dispose
)。它被翻译成
try/finally
,并在finally
中调用Dispose
。最后,顾名思义,即使您调用return
也会调用它。The DataTable is disposed (
.Dispose
is called) in both cases.It's translated into a
try/finally
, withDispose
being called in thefinally
. Finally, as the name implies, is called even when you callreturn
.在您的两个示例中,都会调用
Dispose
。这是因为 using 语句扩展为 try/finally 块。请阅读 C# 语言规范(8.13 using 语句)找出各种场景(引用类型、不可空值类型和动态类型)。
由于
DataTable
是引用类型,因此您的第一个示例将扩展为以下内容:In both your examples,
Dispose
will be called. This is because the using statement expands to a try/finally block.Go read the C# Language Specification (8.13 The using statement) to find out the various scenarios (for reference types, non-nullable value types, and dynamic types).
Since
DataTable
is a reference type, your first sample will expand to the following:using
语句只是语法糖,它被翻译成 try/finally 块。从您的代码开始,C# 编译器将如何将using
块转换为 try/finally 块。从代码中可以看出,无论 return 语句如何,resultTable 都会被释放。 using 块仅确保对象在作用域之后被释放。
您的第一个代码对我来说看起来不错,不需要更改。
using
statement is just syntactic sugar and it gets translated into try/finally block. Starting with your code, here's how the C# compiler will translate theusing
block into try/finally block.As you can see from the code, the resultTable gets disposed for sure regardless of the return statement. The using block only makes sure that object gets disposed after the scope.
Your first code looks ok to me and need not be changed.