Является ли хорошей практикой использование «использования» в новой пустой DataTable? - PullRequest
4 голосов
/ 29 мая 2019

Я переписал старый код, чтобы в моих таблицах данных использовался оператор 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
}

Это хорошая практика (т. Е. Создание таблицы данных empty с оператором using)? Я не знаю почему, но это не совсем правильно.

Ответы [ 3 ]

5 голосов
/ 29 мая 2019

Как я уже говорил в комментариях, ваш последний пример не сработает.Если вы хотите сделать что-то подобное, вы можете переместить генерацию DataTable в отдельную функцию:

public DataTable GetBLLDataTable()
{
    switch(foo)
    {
        case bar:
            return BLL.GetDataTable(bar);
            break;
        default:
            return BLL.GetDataTable();
            break;
    }
}

и затем использовать DataTable, возвращаемый этим методом, в вашем операторе using:

using (DataTable dt = GetBLLDataTable()) {
    // iteration logic here
}
4 голосов
/ 29 мая 2019

В последнем примере вы удаляете только первый объект 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 голосов
/ 29 мая 2019

Просто другой подход, но похожий на тот, что сказал Джон. Вы можете использовать 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
 }

Лично я предпочел бы подход Джона, он немного более читабелен. Но все делают то же самое, так что вы можете использовать то, что вам нравится больше всего.

...