在新的空数据表上使用“使用”是一种好习惯吗?

时间:2019-05-29 08:41:03

标签: c# idisposable using-statement

我一直在重写一些旧代码,以便将using语句用于我的DataTables,而不是每次都记住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
}

这是一种好习惯吗(即使用empty语句创建using DataTable)?我不知道为什么,但是感觉不对。

3 个答案:

答案 0 :(得分:5)

正如我在评论中所述,您的最后一个示例将不起作用。如果您想执行类似的操作,则可以将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
}

答案 1 :(得分:4)

在最后一个示例中,您只处理第一个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对象始终处于废弃状态。在这种情况下,这是一个很奇怪的示例,因为我不明白为什么要在DataTable中分配一个switch,然后立即将其丢弃。

答案 2 :(得分:2)

只是另一种方法,但与约翰所说的相似。您可以使用func<>设置get方法并在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
 }

我个人更喜欢约翰斯的方法,它更具可读性。但是,所有操作都一样,因此您可以使用自己最喜欢的功能。