在新的空 DataTable 上使用 "using" 是一种好习惯吗?
Is it good practice to use "using" on a new empty DataTable?
我一直在重写一些旧代码,以便 using
语句用于我的数据表,而不是每次都记住 Dispose
:
using (DataTable dt = BLL.GetDataTable()) {
foreach(DataRow dr in dt.Rows) {
// iteration logic
}
}
但是在一种特殊情况下,DataTable 的内容因变量而异,因此我创建了初始 DataTable,然后再赋值:
DataTable dt = new DataTable();
switch(foo) {
case bar:
dt = BLL.GetDataTable(bar);
break;
default:
dt = BLL.GetDataTable();
break;
}
// iteration logic here
dt.Dispose();
将此更改为使用 using
,我有:
using (DataTable dt = new DataTable()) {
switch(foo) {
case bar:
dt = BLL.GetDataTable(bar);
break;
default:
dt = BLL.GetDataTable();
break;
}
// iteration logic here
}
这是好的做法吗(即使用 using
语句创建 empty
DataTable)?不知道为什么,就是感觉不太对。
在你的最后一个例子中,你只处理了第一个 DataTable 对象,而不是另一个被分配的对象。
using
语句只是 try/finally
的语法糖。您可以改写最后一个示例,例如:
DataTable dt;
try
{
switch (foo)
{
case bar:
dt = BLL.GetDataTable(bar);
break;
default:
dt = BLL.GetDataTable();
break;
}
}
finally
{
dt?.Dispose();
}
这将确保您的 IDisposable
对象始终被释放。在这种情况下,这是一个有点奇怪的例子,因为我不明白你为什么要在 switch
中分配一个 DataTable
然后立即处理它。
正如我在评论中所述,您的最后一个示例将不起作用。如果你想做类似的事情,你可以将 DataTable 生成移动到一个单独的函数中:
public DataTable GetBLLDataTable()
{
switch(foo)
{
case bar:
return BLL.GetDataTable(bar);
break;
default:
return BLL.GetDataTable();
break;
}
}
然后在你的using语句中使用这个方法返回的DataTable:
using (DataTable dt = GetBLLDataTable()) {
// iteration logic here
}
只是另一种方法,但与 John 所说的类似。您可以使用 func<>
来设置您的获取方法并在 using()
中使用它
Func<DataTable> func = null;
switch (foo)
{
case bar:
func = () => BLL.GetDataTable(bar);
break;
default:
func = () => BLL.GetDataTable();
break;
}
using (var dt = func())
{
// iteration logic here
}
就我个人而言,我更喜欢 Johns 的方法,它更具可读性。但是都是一样的,所以还是要用自己喜欢的。
我一直在重写一些旧代码,以便 using
语句用于我的数据表,而不是每次都记住 Dispose
:
using (DataTable dt = BLL.GetDataTable()) {
foreach(DataRow dr in dt.Rows) {
// iteration logic
}
}
但是在一种特殊情况下,DataTable 的内容因变量而异,因此我创建了初始 DataTable,然后再赋值:
DataTable dt = new DataTable();
switch(foo) {
case bar:
dt = BLL.GetDataTable(bar);
break;
default:
dt = BLL.GetDataTable();
break;
}
// iteration logic here
dt.Dispose();
将此更改为使用 using
,我有:
using (DataTable dt = new DataTable()) {
switch(foo) {
case bar:
dt = BLL.GetDataTable(bar);
break;
default:
dt = BLL.GetDataTable();
break;
}
// iteration logic here
}
这是好的做法吗(即使用 using
语句创建 empty
DataTable)?不知道为什么,就是感觉不太对。
在你的最后一个例子中,你只处理了第一个 DataTable 对象,而不是另一个被分配的对象。
using
语句只是 try/finally
的语法糖。您可以改写最后一个示例,例如:
DataTable dt;
try
{
switch (foo)
{
case bar:
dt = BLL.GetDataTable(bar);
break;
default:
dt = BLL.GetDataTable();
break;
}
}
finally
{
dt?.Dispose();
}
这将确保您的 IDisposable
对象始终被释放。在这种情况下,这是一个有点奇怪的例子,因为我不明白你为什么要在 switch
中分配一个 DataTable
然后立即处理它。
正如我在评论中所述,您的最后一个示例将不起作用。如果你想做类似的事情,你可以将 DataTable 生成移动到一个单独的函数中:
public DataTable GetBLLDataTable()
{
switch(foo)
{
case bar:
return BLL.GetDataTable(bar);
break;
default:
return BLL.GetDataTable();
break;
}
}
然后在你的using语句中使用这个方法返回的DataTable:
using (DataTable dt = GetBLLDataTable()) {
// iteration logic here
}
只是另一种方法,但与 John 所说的类似。您可以使用 func<>
来设置您的获取方法并在 using()
Func<DataTable> func = null;
switch (foo)
{
case bar:
func = () => BLL.GetDataTable(bar);
break;
default:
func = () => BLL.GetDataTable();
break;
}
using (var dt = func())
{
// iteration logic here
}
就我个人而言,我更喜欢 Johns 的方法,它更具可读性。但是都是一样的,所以还是要用自己喜欢的。