在新的空 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 的方法,它更具可读性。但是都是一样的,所以还是要用自己喜欢的。